Skip to content

Commit

Permalink
feat: test claim astro rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
emidev98 committed Jan 24, 2024
1 parent 9fac205 commit c953d4a
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 81 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ node_modules

# Metadata from deployments
scripts/.oracle_address.log
scripts/.hub_address.log
scripts/.hub_address.log

# Code coverage file
lcov.info
3 changes: 3 additions & 0 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ args = ["test", "--locked"]
[tasks.test-cover]
script = """docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin"""

[tasks.test-cover-to-file]
script = "cargo tarpaulin --out Lcov"

[tasks.lint]
command = "cargo"
args = ["clippy", "--tests", "--", "-D", "warnings"]
Expand Down
68 changes: 37 additions & 31 deletions contracts/alliance-lp-hub/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub fn execute(
) -> Result<Response, ContractError> {
match msg {
// Used to whitelist, modify or delete assets from the allowed list
ExecuteMsg::ModifyAssetPairs(assets) => modify_assets(deps, info, assets),
ExecuteMsg::ModifyAssetPairs(assets) => modify_asset(deps, info, assets),

// User interactions Stake, Unstake and ClaimRewards
ExecuteMsg::Receive(cw20_msg) => {
Expand Down Expand Up @@ -131,16 +131,24 @@ pub fn execute(

// This method iterate through the list of assets to be modified,
// for each asset it checks if it is being listed or delisted,
fn modify_assets(
fn modify_asset(
deps: DepsMut,
info: MessageInfo,
assets: Vec<ModifyAssetPair>,
) -> Result<Response, ContractError> {
let config = CONFIG.load(deps.storage)?;
is_governance(&info, &config)?;
let mut attrs = vec![("action".to_string(), "modify_assets".to_string())];
let mut attrs = vec![("action".to_string(), "modify_asset".to_string())];

for asset in assets {
let reward_asset_info_key = match asset.reward_asset_info {
Some(reward_asset_info) => AssetInfoKey::from(reward_asset_info),
None => {
return Err(ContractError::MissingRewardAsset(
asset.asset_info.to_string(),
))
}
};
if asset.delete {
let asset_key = AssetInfoKey::from(asset.asset_info.clone());
WHITELIST.remove(deps.storage, asset_key.clone());
Expand All @@ -150,14 +158,6 @@ fn modify_assets(
]);
} else {
let asset_key = AssetInfoKey::from(asset.asset_info.clone());
let reward_asset_info_key = match asset.reward_asset_info {
Some(reward_asset_info) => AssetInfoKey::from(reward_asset_info),
None => {
return Err(ContractError::MissingRewardAsset(
asset.asset_info.to_string(),
))
}
};

WHITELIST.save(deps.storage, asset_key.clone(), &Decimal::zero())?;
ASSET_REWARD_RATE.update(
Expand Down Expand Up @@ -259,9 +259,7 @@ fn stake(
})
}
_ => {
return Err(ContractError::AssetNotWhitelisted(
received_asset.info.to_string(),
));
return Err(ContractError::InvalidDenom(received_asset.info.to_string()));
}
};

Expand Down Expand Up @@ -540,14 +538,20 @@ fn _update_astro_rewards(
contract_addr: Addr,
astro_incentives: Addr,
) -> Result<Option<SubMsg>, ContractError> {
let whitelist = WHITELIST
.range_raw(deps.storage, None, None, Order::Ascending)
.map(|r| r.map(|(a, d)| (AssetInfoKey(a), d)))
.collect::<StdResult<Vec<(AssetInfoKey, Decimal)>>>()?;
let mut whitelist: Vec<String> = Vec::new();

for f in WHITELIST.range(deps.storage, None, None, Order::Ascending) {
let (asset_info, _) = f?;
let asset_info = asset_info.check(deps.api, None)?;
let asset_string = asset_info.to_string();
let asset_denom = asset_string.split(":").collect::<Vec<&str>>()[1].to_string();

whitelist.push(asset_denom);
}

let mut lp_tokens_list: Vec<String> = vec![];

for (asset_info, _) in whitelist {
let lp_token = String::from_utf8(asset_info.0)?;
for lp_token in whitelist {
let pending_rewards: Vec<Asset> = deps
.querier
.query_wasm_smart(
Expand Down Expand Up @@ -845,23 +849,24 @@ fn reply_claim_astro_rewards(
// and group all the **claimed_reward** for each claimed position.
let mut astro_claims: Vec<AstroClaimRewardsPosition> = vec![];
let mut astro_claim = AstroClaimRewardsPosition::default();
let mut add_to_next_claim_position = false;
let mut count_claim_position = true;
for attr in event.attributes.iter() {
if attr.key == "claimed_position" {
if add_to_next_claim_position {
astro_claims.push(astro_claim.clone());
astro_claim = AstroClaimRewardsPosition::default();
add_to_next_claim_position = false;
} else {
astro_claim.deposited_asset = attr.value.clone();
}
if attr.key == "claimed_position" && count_claim_position {
astro_claim = AstroClaimRewardsPosition::default();
astro_claim.deposited_asset = attr.value.clone();
count_claim_position = false;
}

if attr.key == "claimed_reward" {
let coin = CwCoin::from_str(&attr.value)?;
astro_claim.rewards.add(coin)?;
add_to_next_claim_position = true
}

if attr.key == "claimed_reward" && !count_claim_position {
astro_claims.push(astro_claim.clone());
count_claim_position = true
}

}

// Given the claimed rewards account them to the state of the contract
Expand All @@ -875,12 +880,13 @@ fn reply_claim_astro_rewards(
for reward in claim.rewards {
let reward_asset_key = from_string_to_asset_info(reward.denom)?;
let reward_ammount = Decimal::from_atomics(reward.amount, 0)?;
let mut asset_reward_rate = Decimal::zero();

ASSET_REWARD_RATE.update(
deps.storage,
(deposit_asset_key.clone(), reward_asset_key),
|a| -> StdResult<_> {
let mut asset_reward_rate = a.unwrap_or_default();
asset_reward_rate = a.unwrap_or_default();
asset_reward_rate = (reward_ammount / total_lp_staked) + asset_reward_rate;
Ok(asset_reward_rate)
},
Expand Down
19 changes: 9 additions & 10 deletions contracts/alliance-lp-hub/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use alliance_protocol::alliance_protocol::{
AllianceDelegateMsg, AllianceDelegation, AllianceRedelegateMsg, AllianceRedelegation,
AllianceUndelegateMsg,
};
use alliance_protocol::error::ContractError;
use alliance_protocol::token_factory::CustomExecuteMsg;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coin, from_json, Addr, Binary, Deps, DepsMut, Response, StdResult, Uint128};
Expand Down Expand Up @@ -43,22 +44,22 @@ pub fn set_alliance_asset(deps: DepsMut) {
.unwrap();
}

pub fn modify_asset(deps: DepsMut, assets: Vec<ModifyAssetPair>) -> Response {
pub fn modify_asset(deps: DepsMut, assets: Vec<ModifyAssetPair>) -> Result<Response, ContractError> {
let info = mock_info("gov", &[]);
let env = mock_env();

let msg = ExecuteMsg::ModifyAssetPairs(assets);
execute(deps, env, info, msg).unwrap()
execute(deps, env, info, msg)
}

pub fn stake(deps: DepsMut, user: &str, amount: u128, denom: &str) -> Response {
pub fn stake(deps: DepsMut, user: &str, amount: u128, denom: &str) -> Result<Response, ContractError> {
let info = mock_info(user, &[coin(amount, denom)]);
let env = mock_env();
let msg = ExecuteMsg::Stake {};
execute(deps, env, info, msg).unwrap()
execute(deps, env, info, msg)
}

pub fn stake_cw20(deps: DepsMut, user: &str, amount: u128, denom: &str) -> Response {
pub fn stake_cw20(deps: DepsMut, user: &str, amount: u128, denom: &str) -> Result<Response, ContractError> {
let mut info = mock_info(user, &[]);
let env = mock_env();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
Expand All @@ -67,16 +68,14 @@ pub fn stake_cw20(deps: DepsMut, user: &str, amount: u128, denom: &str) -> Respo
msg: Binary::default(),
});
info.sender = Addr::unchecked(denom.to_owned());
execute(deps, env, info, msg).unwrap()
execute(deps, env, info, msg)
}

pub fn unstake(deps: DepsMut, user: &str, asset: Asset) -> Response {
pub fn unstake(deps: DepsMut, user: &str, asset: Asset) -> Result<Response, ContractError> {
let info = mock_info(user, &[]);
let env = mock_env();
let msg = ExecuteMsg::Unstake(asset);
let res = execute(deps, env, info, msg);

res.unwrap()
execute(deps, env, info, msg)
}

pub fn alliance_delegate(deps: DepsMut, delegations: Vec<(&str, u128)>) -> Response {
Expand Down
4 changes: 2 additions & 2 deletions contracts/alliance-lp-hub/src/tests/mock_querier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl WasmMockQuerier {
panic!("The only mocked tokens are 'astro_existent_cw20' and 'astro_existent_native_coin' you send {}",lp_token)
}
QueryAstroMsg::PendingRewards { lp_token, user: _ } => {
if lp_token == "astro_native_with_existent_rewards" {
if lp_token == "factory/astro_native_with_existent_rewards" {
let msg = vec![Asset {
info: AssetInfoBase::native(lp_token.to_string()),
amount: Uint128::one(),
Expand All @@ -79,7 +79,7 @@ impl WasmMockQuerier {
}];
return SystemResult::Ok(to_json_binary(&msg).into());
}
panic!("The only mocked token with pending rewards is 'astro_native_with_existent_rewards' {}",lp_token)
panic!("The only mocked token with pending rewards is 'factory/astro_native_with_existent_rewards' {}",lp_token)
}
},
_ => self.base.handle_query(request),
Expand Down
1 change: 1 addition & 0 deletions contracts/alliance-lp-hub/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ mod instantiate;
mod mock_querier;
mod rewards;
mod stake_unstake;
mod modify_asset;
76 changes: 76 additions & 0 deletions contracts/alliance-lp-hub/src/tests/modify_asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::models::ModifyAssetPair;
use crate::tests::helpers::{modify_asset, setup_contract, stake};
use alliance_protocol::error::ContractError;
use cosmwasm_std::{Response, testing::mock_dependencies};
use cw_asset::AssetInfo;

#[test]
fn test_stake_non_whitelisted_asset() {
let mut deps = mock_dependencies();
setup_contract(deps.as_mut());

let err = stake(deps.as_mut(), "user1", 100, "native_asset").unwrap_err();

assert_eq!(
err,
ContractError::AssetNotWhitelisted("native:native_asset".to_string())
);
}

#[test]
fn test_remove_asset() {
let mut deps = mock_dependencies();
setup_contract(deps.as_mut());

// Whitelist the pair aWHALE-uluna successfully
let res = modify_asset(
deps.as_mut(),
Vec::from([ModifyAssetPair {
asset_info: AssetInfo::Native("aWHALE".to_string()),
reward_asset_info: Some(AssetInfo::Native("uluna".to_string())),
delete: false,
}]),
)
.unwrap();
assert_eq!(
res,
Response::default()
.add_attributes(vec![("action", "modify_asset"), ("asset", "native:aWHALE"),])
);

// Try to remove the asset aWHALE, it should error because
// the reward_asset_info is not defined
let err = modify_asset(
deps.as_mut(),
Vec::from([ModifyAssetPair {
asset_info: AssetInfo::Native("aWHALE".to_string()),
reward_asset_info: None,
delete: true,
}]),
)
.unwrap_err();
assert_eq!(
err,
ContractError::MissingRewardAsset("native:aWHALE".to_string())
);

// Remove the asset pair aWHALE-uluna successfully because both
// assets are defined
let res = modify_asset(
deps.as_mut(),
Vec::from([ModifyAssetPair {
asset_info: AssetInfo::Native("aWHALE".to_string()),
reward_asset_info: Some(AssetInfo::Native("uluna".to_string())),
delete: true,
}]),
)
.unwrap();
assert_eq!(
res,
Response::default().add_attributes(vec![
("action", "modify_asset"),
("asset", "native:aWHALE"),
("to_remove", "true"),
])
);
}
Loading

0 comments on commit c953d4a

Please sign in to comment.