From ea56af91edc8b2e3b0c1922c30379a0b3e9364b2 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Fri, 12 Jan 2024 18:08:35 +0200 Subject: [PATCH] feat: alliance lp hub tests to stake astro --- .../alliance-hub/src/tests/stake_unstake.rs | 2 +- contracts/alliance-lp-hub/src/contract.rs | 10 +- contracts/alliance-lp-hub/src/query.rs | 2 - .../alliance-lp-hub/src/tests/mock_querier.rs | 77 ++++++++++ contracts/alliance-lp-hub/src/tests/mod.rs | 1 + .../alliance-lp-hub/src/tests/rewards.rs | 3 +- .../src/tests/stake_unstake.rs | 138 ++++++++++++++---- 7 files changed, 196 insertions(+), 37 deletions(-) create mode 100644 contracts/alliance-lp-hub/src/tests/mock_querier.rs diff --git a/contracts/alliance-hub/src/tests/stake_unstake.rs b/contracts/alliance-hub/src/tests/stake_unstake.rs index 30b5cae..244a899 100644 --- a/contracts/alliance-hub/src/tests/stake_unstake.rs +++ b/contracts/alliance-hub/src/tests/stake_unstake.rs @@ -99,7 +99,7 @@ fn test_stake_invalid() { let msg = ExecuteMsg::Stake {}; let info = mock_info("user1", &[coin(100, "asset2")]); let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); - assert_eq!(err, ContractError::AssetNotWhitelisted("native:asset1".to_string())); + assert_eq!(err, ContractError::AssetNotWhitelisted("native:asset2".to_string())); // Stake multiple assets in a single call let msg = ExecuteMsg::Stake {}; diff --git a/contracts/alliance-lp-hub/src/contract.rs b/contracts/alliance-lp-hub/src/contract.rs index e79f588..fd47436 100644 --- a/contracts/alliance-lp-hub/src/contract.rs +++ b/contracts/alliance-lp-hub/src/contract.rs @@ -10,7 +10,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Addr, Binary, Coin as CwCoin, CosmosMsg, Decimal, DepsMut, Empty, Env, MessageInfo, Reply, Response, StdError, StdResult, Storage, SubMsg, Uint128, WasmMsg, Order}; use cw2::set_contract_version; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; -use cw_asset::{Asset, AssetInfo, AssetInfoKey, AssetInfoUnchecked, AssetInfoBase}; +use cw_asset::{Asset, AssetInfo, AssetInfoKey, AssetInfoUnchecked}; use cw_utils::parse_instantiate_response_data; use std::{collections::HashSet, env}; use std::str::FromStr; @@ -178,13 +178,15 @@ fn stake( } let config = CONFIG.load(deps.storage)?; - // Query astro incentives + // Query astro incentives, to do so we must first remove the prefix + // from the asset info e.g. cw20:asset1 -> asset1 or native:uluna -> uluna + let lp_token = received_asset.info.to_string(); let astro_incentives: Vec = deps.querier.query_wasm_smart( config.astro_incentives_addr.to_string(), &QueryAstroMsg::RewardInfo{ - lp_token: received_asset.info.to_string(), + lp_token: lp_token.split(":").collect::>()[1].to_string(), }, - )?; + ).unwrap_or_default(); let mut res = Response::new().add_attributes(vec![ ("action", "stake"), diff --git a/contracts/alliance-lp-hub/src/query.rs b/contracts/alliance-lp-hub/src/query.rs index 76eed33..6fffb1e 100644 --- a/contracts/alliance-lp-hub/src/query.rs +++ b/contracts/alliance-lp-hub/src/query.rs @@ -7,9 +7,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Binary, Deps, Env, Order, StdResult, Uint128, Decimal}; use cw_asset::{AssetInfo, AssetInfoKey, AssetInfoUnchecked}; use std::collections::HashMap; -use std::convert::TryFrom; use alliance_protocol::alliance_oracle_types::EmissionsDistribution; -use alliance_protocol::alliance_protocol::AssetDistribution; use alliance_protocol::signed_decimal::{Sign, SignedDecimal}; use crate::state::{ diff --git a/contracts/alliance-lp-hub/src/tests/mock_querier.rs b/contracts/alliance-lp-hub/src/tests/mock_querier.rs new file mode 100644 index 0000000..7e910bc --- /dev/null +++ b/contracts/alliance-lp-hub/src/tests/mock_querier.rs @@ -0,0 +1,77 @@ +use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; +use cosmwasm_std::{ + Coin, Empty, OwnedDeps, Querier, QuerierResult, + QueryRequest, SystemError, SystemResult, WasmQuery, Addr, Decimal, from_json, to_json_binary, from_slice, +}; + +use crate::astro_models::{QueryAstroMsg, RewardInfo, AstroRewardType, AstroAssetInfo}; + +/// mock_dependencies is a drop-in replacement for cosmwasm_std::testing::mock_dependencies. +/// This uses the Astroport CustomQuerier. +pub fn mock_dependencies( + contract_balance: &[Coin], +) -> OwnedDeps { + let custom_querier: WasmMockQuerier = + WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + + OwnedDeps { + storage: MockStorage::default(), + api: MockApi::default(), + querier: custom_querier, + custom_query_type: Default::default(), + } +} + +pub struct WasmMockQuerier { + base: MockQuerier, +} + +impl Querier for WasmMockQuerier { + fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { + // MockQuerier doesn't support Custom, so we ignore it completely + let request: QueryRequest = match from_slice(bin_request) { + Ok(v) => v, + Err(e) => { + return SystemResult::Err(SystemError::InvalidRequest { + error: format!("Parsing query request: {}", e), + request: bin_request.into(), + }) + } + }; + self.handle_query(&request) + } +} + +impl WasmMockQuerier { + pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { + match &request { + QueryRequest::Wasm(WasmQuery::Smart {contract_addr, msg})// => { + => match from_json(&msg).unwrap() { + QueryAstroMsg::RewardInfo { lp_token } => { + if lp_token == "astro_existent_cw20" || lp_token == "astro_existent_native_coin" { + let msg = vec![RewardInfo { + reward: AstroRewardType::Int(AstroAssetInfo::Token { + contract_addr: Addr::unchecked(lp_token), + }), + rps: Decimal::zero(), + index: Decimal::zero(), + orphaned: Decimal::zero(), + }]; + return SystemResult::Ok(to_json_binary(&msg).into()) + } + panic!("The only mocked tokens are 'astro_existent_cw20' and 'astro_existent_native_coin' you send {}",lp_token) + } + _ => panic!("DO NOT ENTER HERE") + } + _ => self.base.handle_query(request), + } + } +} + +impl WasmMockQuerier { + pub fn new(base: MockQuerier) -> Self { + WasmMockQuerier { + base, + } + } +} diff --git a/contracts/alliance-lp-hub/src/tests/mod.rs b/contracts/alliance-lp-hub/src/tests/mod.rs index 8aae736..8dfe1b9 100644 --- a/contracts/alliance-lp-hub/src/tests/mod.rs +++ b/contracts/alliance-lp-hub/src/tests/mod.rs @@ -2,3 +2,4 @@ mod helpers; mod instantiate; mod stake_unstake; mod rewards; +mod mock_querier; \ No newline at end of file diff --git a/contracts/alliance-lp-hub/src/tests/rewards.rs b/contracts/alliance-lp-hub/src/tests/rewards.rs index fdde194..3294e73 100644 --- a/contracts/alliance-lp-hub/src/tests/rewards.rs +++ b/contracts/alliance-lp-hub/src/tests/rewards.rs @@ -5,14 +5,13 @@ use crate::tests::helpers::{ claim_rewards, query_all_rewards, query_rewards, set_alliance_asset, setup_contract, stake, unstake, modify_asset, DENOM, }; -use alliance_protocol::alliance_protocol::AssetDistribution; use cosmwasm_std::testing::{mock_dependencies_with_balance, mock_env, mock_info}; use cosmwasm_std::{ coin, coins, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Decimal, Response, SubMsg, Uint128, WasmMsg, }; use cw_asset::{AssetInfo, AssetInfoKey}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use terra_proto_rs::alliance::alliance::MsgClaimDelegationRewards; use terra_proto_rs::traits::Message; diff --git a/contracts/alliance-lp-hub/src/tests/stake_unstake.rs b/contracts/alliance-lp-hub/src/tests/stake_unstake.rs index 7996a45..5697cc5 100644 --- a/contracts/alliance-lp-hub/src/tests/stake_unstake.rs +++ b/contracts/alliance-lp-hub/src/tests/stake_unstake.rs @@ -1,14 +1,18 @@ +use crate::astro_models::{ExecuteAstroMsg, Cw20Msg}; use crate::contract::execute; -use crate::models::{ExecuteMsg, StakedBalanceRes, ModifyAsset}; +use crate::models::{ExecuteMsg, ModifyAsset, StakedBalanceRes}; use crate::state::{BALANCES, TOTAL_BALANCES}; use crate::tests::helpers::{ - query_all_staked_balances, setup_contract, stake, unstake, modify_asset, stake_cw20 + modify_asset, query_all_staked_balances, setup_contract, stake, stake_cw20, unstake, }; +use crate::tests::mock_querier::mock_dependencies as astro_mock_dependencies; use alliance_protocol::error::ContractError; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{coin, Addr, BankMsg, CosmosMsg, Response, Uint128, Decimal}; +use cosmwasm_std::{ + coin, to_json_binary, Addr, BankMsg, Coin, CosmosMsg, Response, Uint128, WasmMsg, +}; +use cw20::{Cw20ReceiveMsg, Cw20ExecuteMsg}; use cw_asset::{Asset, AssetInfo, AssetInfoKey}; -use std::collections::HashMap; #[test] fn test_stake() { @@ -16,12 +20,10 @@ fn test_stake() { setup_contract(deps.as_mut()); modify_asset( deps.as_mut(), - vec![ - ModifyAsset { - asset_info: AssetInfo::native(Addr::unchecked("native_asset")), - delete: false, - } - ] + vec![ModifyAsset { + asset_info: AssetInfo::native(Addr::unchecked("native_asset")), + delete: false, + }], ); let res = stake(deps.as_mut(), "user1", 100, "native_asset"); @@ -86,18 +88,62 @@ fn test_stake() { ); } +#[test] +fn test_stake_astro_token() { + let mut deps = astro_mock_dependencies(&vec![Coin::new(1000, "token")]); + setup_contract(deps.as_mut()); + modify_asset( + deps.as_mut(), + vec![ModifyAsset { + asset_info: AssetInfo::native(Addr::unchecked("astro_existent_native_coin")), + delete: false, + }], + ); + + let res = stake(deps.as_mut(), "user1", 100, "astro_existent_native_coin"); + + assert_eq!( + res, + Response::default() + .add_attributes(vec![ + ("action", "stake"), + ("user", "user1"), + ("asset", "native:astro_existent_native_coin"), + ("amount", "100"), + ]) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "astro_incentives".to_string(), + msg: to_json_binary(&ExecuteAstroMsg::Deposit { recipient: None }).unwrap(), + funds: vec![Coin { + denom: "astro_existent_native_coin".to_string(), + amount: Uint128::new(100), + }], + })) + ); + + let balance = BALANCES + .load( + deps.as_ref().storage, + ( + Addr::unchecked("user1"), + AssetInfoKey::from(AssetInfo::Native("astro_existent_native_coin".to_string())), + ), + ) + .unwrap(); + assert_eq!(balance, Uint128::new(100)); + +} + #[test] fn test_stake_cw20() { let mut deps = mock_dependencies(); setup_contract(deps.as_mut()); modify_asset( deps.as_mut(), - vec![ - ModifyAsset { - asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), - delete: false, - } - ] + vec![ModifyAsset { + asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), + delete: false, + }], ); let res = stake_cw20(deps.as_mut(), "user1", 100, "cw20_asset"); @@ -162,6 +208,46 @@ fn test_stake_cw20() { ); } +#[test] +fn test_stake_astro_token_cw20() { + let mut deps = astro_mock_dependencies(&vec![Coin::new(1000, "token")]); + setup_contract(deps.as_mut()); + modify_asset( + deps.as_mut(), + vec![ModifyAsset { + asset_info: AssetInfo::Cw20(Addr::unchecked("astro_existent_cw20")), + delete: false, + }], + ); + + let res = stake_cw20(deps.as_mut(), "user1", 100, "astro_existent_cw20"); + assert_eq!( + res, + Response::default().add_attributes(vec![ + ("action", "stake"), + ("user", "user1"), + ("asset", "cw20:astro_existent_cw20"), + ("amount", "100"), + ]) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "astro_existent_cw20".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "astro_incentives".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20ReceiveMsg { + sender: "cosmos2contract".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20Msg::Deposit { + recipient: None, + }).unwrap(), + }).unwrap(), + }).unwrap(), + funds: vec![], + })) + ); +} + + #[test] fn test_unstake() { let mut deps = mock_dependencies(); @@ -169,12 +255,10 @@ fn test_unstake() { modify_asset( deps.as_mut(), - vec![ - ModifyAsset { - asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), - delete: false, - } - ] + vec![ModifyAsset { + asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), + delete: false, + }], ); stake_cw20(deps.as_mut(), "user1", 100, "cw20_asset"); @@ -248,12 +332,10 @@ fn test_unstake_invalid() { modify_asset( deps.as_mut(), - vec![ - ModifyAsset { - asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), - delete: false, - } - ] + vec![ModifyAsset { + asset_info: AssetInfo::Cw20(Addr::unchecked("cw20_asset")), + delete: false, + }], ); stake_cw20(deps.as_mut(), "user1", 100, "cw20_asset");