Skip to content

Commit 243bc7e

Browse files
committed
whitelist for reward CW20 tokens
1 parent 2c00c34 commit 243bc7e

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

contracts/multi_staking/src/contract.rs

+33
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub fn instantiate(
8080
owner: deps.api.addr_validate(msg.owner.as_str())?,
8181
allowed_lp_tokens: vec![],
8282
unbond_config: msg.unbond_config.clone(),
83+
allowed_reward_cw20_tokens: vec![],
8384
},
8485
)?;
8586

@@ -187,6 +188,29 @@ pub fn execute(
187188
ExecuteMsg::ClaimUnallocatedReward { reward_schedule_id } => {
188189
claim_unallocated_reward(deps, env, info, reward_schedule_id)
189190
}
191+
ExecuteMsg::AllowRewardCw20Token { addr } => {
192+
let mut config = CONFIG.load(deps.storage)?;
193+
if config.allowed_reward_cw20_tokens.contains(&addr) {
194+
return Err(ContractError::Cw20TokenAlreadyAllowed);
195+
}
196+
config.allowed_reward_cw20_tokens.push(addr.clone());
197+
CONFIG.save(deps.storage, &config)?;
198+
199+
Ok(Response::new().add_event(
200+
Event::from_info(concatcp!(CONTRACT_NAME, "::allow_reward_cw20_token"), &info)
201+
.add_attribute("cw20_token", addr.to_string()),
202+
))
203+
},
204+
ExecuteMsg::RemoveRewardCw20Token { addr } => {
205+
let mut config = CONFIG.load(deps.storage)?;
206+
config.allowed_reward_cw20_tokens.retain(|x| x != &addr);
207+
CONFIG.save(deps.storage, &config)?;
208+
209+
Ok(Response::new().add_event(
210+
Event::from_info(concatcp!(CONTRACT_NAME, "::remove_reward_cw20_token"), &info)
211+
.add_attribute("cw20_token", addr.to_string()),
212+
))
213+
},
190214
ExecuteMsg::ProposeNewOwner { owner, expires_in } => {
191215
let config = CONFIG.load(deps.storage)?;
192216
let response = propose_new_owner(
@@ -619,6 +643,11 @@ pub fn receive_cw20(
619643

620644
let token_addr = info.sender.clone();
621645

646+
// validate that the CW20 token is allowed for rewards
647+
if !config.allowed_reward_cw20_tokens.contains(&token_addr) {
648+
return Err(ContractError::Cw20TokenNotAllowed);
649+
}
650+
622651
let creator = match actual_creator {
623652
Some(creator) => deps.api.addr_validate(&creator.to_string())?,
624653
None => sender.clone(),
@@ -1230,6 +1259,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Resp
12301259
allowed_lp_tokens: config_v1.allowed_lp_tokens,
12311260
keeper: deps.api.addr_validate(&keeper_addr.to_string())?,
12321261
unbond_config,
1262+
allowed_reward_cw20_tokens: vec![],
12331263
};
12341264

12351265
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
@@ -1257,6 +1287,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Resp
12571287
allowed_lp_tokens: config_v2.allowed_lp_tokens,
12581288
keeper: deps.api.addr_validate(&keeper_addr.to_string())?,
12591289
unbond_config,
1290+
allowed_reward_cw20_tokens: vec![],
12601291
};
12611292

12621293
CONFIG.save(deps.storage, &config)?;
@@ -1289,6 +1320,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Resp
12891320
allowed_lp_tokens: config_v2.allowed_lp_tokens,
12901321
keeper: config_v2.keeper,
12911322
unbond_config,
1323+
allowed_reward_cw20_tokens: vec![],
12921324
};
12931325

12941326
CONFIG.save(deps.storage, &config)?;
@@ -1323,6 +1355,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Resp
13231355
allowed_lp_tokens: config_v3.allowed_lp_tokens,
13241356
keeper: config_v3.keeper,
13251357
unbond_config,
1358+
allowed_reward_cw20_tokens: vec![],
13261359
};
13271360

13281361
CONFIG.save(deps.storage, &config)?;

contracts/multi_staking/src/error.rs

+6
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ pub enum ContractError {
118118

119119
#[error("Invalid unbond config. Error: {error}")]
120120
InvalidUnbondConfig { error: UnbondConfigValidationError },
121+
122+
#[error("CW20 Token is already allowed as a reward asset")]
123+
Cw20TokenAlreadyAllowed,
124+
125+
#[error("This CW20 Token is not allowed as a reward asset")]
126+
Cw20TokenNotAllowed,
121127
}
122128

123129
impl From<OverflowError> for ContractError {

packages/dexter/src/multi_staking.rs

+11
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ pub struct Config {
105105
pub keeper: Addr,
106106
/// LP Token addresses for which reward schedules can be added
107107
pub allowed_lp_tokens: Vec<Addr>,
108+
/// Allowed CW20 tokens for rewards. This is to control the abuse from a malicious CW20 token to create
109+
/// unnecessary reward schedules
110+
pub allowed_reward_cw20_tokens: Vec<Addr>,
108111
/// Default unbond config
109112
pub unbond_config: UnbondConfig
110113
}
@@ -402,6 +405,14 @@ pub enum ExecuteMsg {
402405
RemoveLpToken {
403406
lp_token: Addr,
404407
},
408+
/// Add reward CW20 token to the list of allowed reward tokens
409+
AllowRewardCw20Token {
410+
addr: Addr
411+
},
412+
/// Remove reward CW20 token from the list of allowed reward tokens
413+
RemoveRewardCw20Token {
414+
addr: Addr,
415+
},
405416
/// Allows the contract to receive CW20 tokens.
406417
/// The contract can receive CW20 tokens from LP tokens for staking and
407418
/// CW20 assets to be used as rewards.

0 commit comments

Comments
 (0)