From bf1b38d414420a79171a858e5c4c813eadd4ef2a Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Tue, 23 Jan 2024 22:57:47 +0200 Subject: [PATCH 01/15] Fee splitter: adds tests to the fee_splitter --- Cargo.lock | 1 + Cargo.toml | 1 + contracts/fee_splitter/Cargo.toml | 2 +- contracts/fee_splitter/src/contract.rs | 11 +-- contracts/fee_splitter/src/testing.rs | 114 +++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c31787..efcec5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,6 +698,7 @@ dependencies = [ "cw20", "cw20-base", "dex", + "dex-factory", "dex-pool", "dex-stake", "itertools", diff --git a/Cargo.toml b/Cargo.toml index 16d95e0..d4fb32b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ dex = { path = "./packages/dex", default-features = false } dex-factory = { path = "./contracts/factory", default-features = false } dex-pool = { path = "./contracts/pool", default-features = false } dex-stake = { path = "./contracts/stake", default-features = false } +dex-fee-splitter = { path = "./contracts/fee_splitter", default-features = false } itertools = "0.10" proptest = "1.0" schemars = "0.8" diff --git a/contracts/fee_splitter/Cargo.toml b/contracts/fee_splitter/Cargo.toml index e8aa330..6cdbf28 100644 --- a/contracts/fee_splitter/Cargo.toml +++ b/contracts/fee_splitter/Cargo.toml @@ -31,6 +31,6 @@ anyhow = { workspace = true } bindings-test = { workspace = true } cw-multi-test = { workspace = true } cw20-base = { workspace = true } -# dex-factory = { workspace = true } +dex-factory = { workspace = true } dex-pool = { workspace = true } dex-stake = { workspace = true } diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index 82a81b5..c149a1d 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -73,8 +73,10 @@ fn execute_send_tokens( native_denoms: Vec, cw20_addresses: Vec, ) -> Result { + dbg!("before"); let config = query_config(deps)?; + dbg!("after"); let contract_address = env.contract.address.to_string(); // gather balances of native tokens, either from function parameter or all let native_balances = native_denoms @@ -162,12 +164,3 @@ pub fn query_config(deps: Deps) -> StdResult { Ok(resp) } - -#[cfg(test)] -mod tests { - #[test] - #[ignore] - fn instantiate_with_invalid_weights_should_throw_error() { - todo!() - } -} diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 8b13789..2bcd9a2 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -1 +1,115 @@ +use bindings_test::{mock_coreum_deps, CoreumApp}; +use cosmwasm_std::{testing::mock_env, Addr, Decimal}; +use cw_multi_test::{ContractWrapper, Executor}; +use crate::{ + contract::execute, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + state::Config, +}; + +#[test] +fn init_works() { + let mut app = CoreumApp::default(); + + let code_id = store_fee_splitter_code(&mut app); + let sender = "addr0000"; + + let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)); + let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)); + let msg = InstantiateMsg { + addresses: vec![first_tupple.clone(), second_tuple.clone()], + cw20_contracts: vec!["cw20_contract_one".to_string()], + }; + + let fee_splitter_instance = app + .instantiate_contract( + code_id, + Addr::unchecked(sender), + &msg, + &[], + "fee-splitter", + None, + ) + .unwrap(); + + let config_response: Config = app + .wrap() + .query_wasm_smart(fee_splitter_instance, &QueryMsg::Config {}) + .unwrap(); + + assert_eq!(config_response.addresses, vec![first_tupple, second_tuple]); +} + +#[test] +#[should_panic(expected = "Provided weights exceed maximum allowed value")] +fn fails_to_init_because_weights_not_correct() { + let mut app = CoreumApp::default(); + + let code_id = store_fee_splitter_code(&mut app); + let sender = "addr0000"; + + let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(2u128, 1u128)); + let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(2u128, 1u128)); + let msg = InstantiateMsg { + addresses: vec![first_tupple.clone(), second_tuple.clone()], + cw20_contracts: vec!["cw20_contract_one".to_string()], + }; + + app.instantiate_contract( + code_id, + Addr::unchecked(sender), + &msg, + &[], + "fee-splitter", + None, + ) + .unwrap(); +} + +#[test] +fn should_send_tokens_in_correct_amount() { + let mut app = CoreumApp::default(); + + let code_id = store_fee_splitter_code(&mut app); + let sender = "addr0000"; + + let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)); + let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)); + let msg = InstantiateMsg { + addresses: vec![first_tupple.clone(), second_tuple.clone()], + cw20_contracts: vec!["cw20_contract_one".to_string()], + }; + + let _ = app + .instantiate_contract( + code_id, + Addr::unchecked(sender), + &msg, + &[], + "fee-splitter", + None, + ) + .unwrap(); + + let deps = mock_coreum_deps(); + let env = mock_env(); + let msg = ExecuteMsg::SendTokens { + native_denoms: vec!["addr0000".to_string(), "addr0001".to_string()], + cw20_addresses: vec!["cw20_contract_one".to_string()], + }; + + let res = execute(deps.as_ref(), env, msg).unwrap(); + ///todo I need to mock more things, start with the query_config + dbg!(res); +} + +fn store_fee_splitter_code(app: &mut CoreumApp) -> u64 { + let fee_splitter_contract = Box::new(ContractWrapper::new( + crate::contract::instantiate, + crate::contract::instantiate, + crate::contract::query, + )); + + app.store_code(fee_splitter_contract) +} From df12aa713962af0127522ba9520c32d05acadfef Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Tue, 23 Jan 2024 22:59:44 +0200 Subject: [PATCH 02/15] Fee splitter: fmt --- contracts/fee_splitter/src/contract.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index c149a1d..fbfdd2a 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -73,10 +73,8 @@ fn execute_send_tokens( native_denoms: Vec, cw20_addresses: Vec, ) -> Result { - dbg!("before"); let config = query_config(deps)?; - dbg!("after"); let contract_address = env.contract.address.to_string(); // gather balances of native tokens, either from function parameter or all let native_balances = native_denoms From b494f3e0be22b396366fdf33a7f9fad6160df6d7 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 31 Jan 2024 15:35:12 +0100 Subject: [PATCH 03/15] Fee splitter: Fix instantiation of the contract in unit test module --- contracts/fee_splitter/src/contract.rs | 10 +++----- contracts/fee_splitter/src/state.rs | 3 +++ contracts/fee_splitter/src/testing.rs | 35 +++++++++++--------------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index fbfdd2a..b74bdf6 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -4,17 +4,13 @@ use cosmwasm_std::{ DepsMut, Env, MessageInfo, StdError, StdResult, WasmMsg, }; use cw20::{BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; -use cw_storage_plus::Item; use crate::{ error::ContractError, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, - state::Config, + state::{Config, CONFIG}, }; -/// Saves factory settings -pub const CONFIG: Item = Item::new("config"); - pub type Response = cosmwasm_std::Response; pub type SubMsg = cosmwasm_std::SubMsg; @@ -73,7 +69,9 @@ fn execute_send_tokens( native_denoms: Vec, cw20_addresses: Vec, ) -> Result { - let config = query_config(deps)?; + dbg!("here"); + let config = CONFIG.load(deps.storage)?; + dbg!("after config"); let contract_address = env.contract.address.to_string(); // gather balances of native tokens, either from function parameter or all diff --git a/contracts/fee_splitter/src/state.rs b/contracts/fee_splitter/src/state.rs index ca0d945..0497f1f 100644 --- a/contracts/fee_splitter/src/state.rs +++ b/contracts/fee_splitter/src/state.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Decimal; +use cw_storage_plus::Item; #[cw_serde] pub struct Config { @@ -7,3 +8,5 @@ pub struct Config { // Weights must sum up to 1.0 pub addresses: Vec<(String, Decimal)>, } + +pub const CONFIG: Item = Item::new("config"); diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 2bcd9a2..4861921 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -1,9 +1,12 @@ use bindings_test::{mock_coreum_deps, CoreumApp}; -use cosmwasm_std::{testing::mock_env, Addr, Decimal}; +use cosmwasm_std::{ + testing::{mock_env, mock_info}, + Addr, Decimal, +}; use cw_multi_test::{ContractWrapper, Executor}; use crate::{ - contract::execute, + contract::{execute, instantiate}, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, state::Config, }; @@ -69,39 +72,29 @@ fn fails_to_init_because_weights_not_correct() { #[test] fn should_send_tokens_in_correct_amount() { - let mut app = CoreumApp::default(); + let mut deps = mock_coreum_deps(); + let env = mock_env(); - let code_id = store_fee_splitter_code(&mut app); let sender = "addr0000"; - let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)); - let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)); + let info = mock_info(sender, &[]); let msg = InstantiateMsg { - addresses: vec![first_tupple.clone(), second_tuple.clone()], + addresses: vec![ + ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)), + ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)), + ], cw20_contracts: vec!["cw20_contract_one".to_string()], }; - let _ = app - .instantiate_contract( - code_id, - Addr::unchecked(sender), - &msg, - &[], - "fee-splitter", - None, - ) - .unwrap(); + let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - let deps = mock_coreum_deps(); - let env = mock_env(); let msg = ExecuteMsg::SendTokens { - native_denoms: vec!["addr0000".to_string(), "addr0001".to_string()], + native_denoms: vec!["A".to_string(), "addr0001".to_string()], cw20_addresses: vec!["cw20_contract_one".to_string()], }; let res = execute(deps.as_ref(), env, msg).unwrap(); ///todo I need to mock more things, start with the query_config - dbg!(res); } fn store_fee_splitter_code(app: &mut CoreumApp) -> u64 { From dd36813c7030318963480d8a4faf811e0e813e03 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Thu, 1 Feb 2024 10:13:52 +0200 Subject: [PATCH 04/15] Fee splitter: adds test for the splitting amount. Bindings test: new file that is responsible for the mocks in fee splitter. --- Cargo.lock | 2 + contracts/fee_splitter/src/contract.rs | 4 +- contracts/fee_splitter/src/testing.rs | 82 +++++++- packages/bindings-test/Cargo.toml | 3 +- .../bindings-test/src/coreum_testing_deps.rs | 188 ++++++++++++++++++ packages/bindings-test/src/lib.rs | 7 +- packages/bindings-test/src/multitest.rs | 16 +- 7 files changed, 273 insertions(+), 29 deletions(-) create mode 100644 packages/bindings-test/src/coreum_testing_deps.rs diff --git a/Cargo.lock b/Cargo.lock index efcec5b..824968a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,8 @@ dependencies = [ "coreum-wasm-sdk", "cosmwasm-std", "cw-multi-test", + "cw20", + "dex", "schemars", "serde", ] diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index b74bdf6..3c28a48 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -46,7 +46,7 @@ pub fn instantiate( CONFIG.save(deps.storage, &config)?; - Ok(Response::new().add_attribute("initialized", "contract")) + Ok(Response::new().add_attribute("initialized", "fee_splitter contract")) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -69,9 +69,7 @@ fn execute_send_tokens( native_denoms: Vec, cw20_addresses: Vec, ) -> Result { - dbg!("here"); let config = CONFIG.load(deps.storage)?; - dbg!("after config"); let contract_address = env.contract.address.to_string(); // gather balances of native tokens, either from function parameter or all diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 4861921..a1d6c19 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -1,7 +1,8 @@ use bindings_test::{mock_coreum_deps, CoreumApp}; +use coreum_wasm_sdk::core::CoreumMsg; use cosmwasm_std::{ - testing::{mock_env, mock_info}, - Addr, Decimal, + testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, + Addr, Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, }; use cw_multi_test::{ContractWrapper, Executor}; @@ -11,6 +12,8 @@ use crate::{ state::Config, }; +pub type SubMsg = cosmwasm_std::SubMsg; + #[test] fn init_works() { let mut app = CoreumApp::default(); @@ -72,7 +75,22 @@ fn fails_to_init_because_weights_not_correct() { #[test] fn should_send_tokens_in_correct_amount() { - let mut deps = mock_coreum_deps(); + let mut deps = mock_coreum_deps(&[]); + + deps.querier.with_balance(&[( + &String::from(MOCK_CONTRACT_ADDR), + &[ + Coin { + denom: "ATOM".to_string(), + amount: Uint128::new(100_000000000000000000), + }, + Coin { + denom: "TIA".to_string(), + amount: Uint128::new(100_000000000000000000), + }, + ], + )]); + let env = mock_env(); let sender = "addr0000"; @@ -80,21 +98,69 @@ fn should_send_tokens_in_correct_amount() { let info = mock_info(sender, &[]); let msg = InstantiateMsg { addresses: vec![ - ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)), - ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)), + ("address0000".to_string(), Decimal::percent(60u64)), + ("address0001".to_string(), Decimal::percent(40u64)), ], - cw20_contracts: vec!["cw20_contract_one".to_string()], + cw20_contracts: vec![], }; let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); + assert_eq!( + fee_splitter_instance.attributes, + vec![Attribute { + key: "initialized".to_string(), + value: "fee_splitter contract".to_string(), + }] + ); let msg = ExecuteMsg::SendTokens { - native_denoms: vec!["A".to_string(), "addr0001".to_string()], + native_denoms: vec!["ATOM".to_string(), "TIA".to_string()], cw20_addresses: vec!["cw20_contract_one".to_string()], }; let res = execute(deps.as_ref(), env, msg).unwrap(); - ///todo I need to mock more things, start with the query_config + + assert_eq!( + res.messages, + vec![ + SubMsg { + id: 0, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "address0000".to_string(), + amount: vec![ + Coin { + denom: "ATOM".to_string(), + amount: Uint128::new(60000000000000000000), + }, + Coin { + denom: "TIA".to_string(), + amount: Uint128::new(60000000000000000000), + } + ] + }), + gas_limit: None, + reply_on: ReplyOn::Never + }, + SubMsg { + id: 0, + msg: CosmosMsg::Bank(BankMsg::Send { + to_address: "address0001".to_string(), + amount: vec![ + Coin { + denom: "ATOM".to_string(), + amount: Uint128::new(40000000000000000000), + }, + Coin { + denom: "TIA".to_string(), + amount: Uint128::new(40000000000000000000), + } + ] + }), + gas_limit: None, + reply_on: ReplyOn::Never + }, + ] + ); } fn store_fee_splitter_code(app: &mut CoreumApp) -> u64 { diff --git a/packages/bindings-test/Cargo.toml b/packages/bindings-test/Cargo.toml index b80f292..21f261a 100644 --- a/packages/bindings-test/Cargo.toml +++ b/packages/bindings-test/Cargo.toml @@ -14,5 +14,6 @@ cosmwasm-std = { workspace = true } cw-multi-test = { workspace = true } schemars = { workspace = true } serde = { workspace = true } - +dex = { workspace = true } +cw20 = { workspace = true } diff --git a/packages/bindings-test/src/coreum_testing_deps.rs b/packages/bindings-test/src/coreum_testing_deps.rs new file mode 100644 index 0000000..ebffee6 --- /dev/null +++ b/packages/bindings-test/src/coreum_testing_deps.rs @@ -0,0 +1,188 @@ +use std::{collections::HashMap, marker::PhantomData}; + +use coreum_wasm_sdk::core::CoreumQueries; +use cosmwasm_std::{ + from_json, + testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, + to_json_binary, Addr, Coin, Decimal, OwnedDeps, Querier, QuerierResult, QueryRequest, + SystemError, SystemResult, Uint128, WasmQuery, +}; +use dex::factory::{ + ConfigResponse, FeeInfoResponse, + QueryMsg::{Config, FeeInfo}, +}; + +use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; + +pub type CoreumDeps = OwnedDeps; + +pub fn mock_coreum_deps(contract_balance: &[Coin]) -> CoreumDeps { + let custom_qurier = + SplitterMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + + CoreumDeps { + storage: MockStorage::default(), + api: MockApi::default(), + querier: custom_qurier, + custom_query_type: PhantomData, + } +} + +pub struct SplitterMockQuerier { + base: MockQuerier, + token_querier: TokenQuerier, +} + +#[derive(Clone, Default)] +pub struct TokenQuerier { + // This lets us iterate over all pools that match the first string + balances: HashMap>, +} + +impl TokenQuerier { + pub fn new(balances: &[(&String, &[(&String, &Uint128)])]) -> Self { + TokenQuerier { + balances: balances_to_map(balances), + } + } +} + +pub(crate) fn balances_to_map( + balances: &[(&String, &[(&String, &Uint128)])], +) -> HashMap> { + let mut balances_map: HashMap> = HashMap::new(); + for (contract_addr, balances) in balances.iter() { + let mut contract_balances_map: HashMap = HashMap::new(); + for (addr, balance) in balances.iter() { + contract_balances_map.insert(addr.to_string(), **balance); + } + + balances_map.insert(contract_addr.to_string(), contract_balances_map); + } + balances_map +} +impl Querier for SplitterMockQuerier { + fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { + // MockQuerier doesn't support Custom, so we ignore it completely + let request: QueryRequest = match from_json(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 SplitterMockQuerier { + pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { + match &request { + QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { + if contract_addr == "factory" { + match from_json(msg).unwrap() { + FeeInfo { .. } => SystemResult::Ok( + to_json_binary(&FeeInfoResponse { + fee_address: Some(Addr::unchecked("fee_address")), + total_fee_bps: 30, + protocol_fee_bps: 1660, + }) + .into(), + ), + Config {} => SystemResult::Ok( + to_json_binary(&ConfigResponse { + owner: Addr::unchecked("owner"), + pool_configs: vec![], + fee_address: Some(Addr::unchecked("fee_address")), + max_referral_commission: Decimal::one(), + only_owner_can_create_pools: true, + trading_starts: None, + }) + .into(), + ), + _ => panic!("DO NOT ENTER HERE"), + } + } else { + match from_json(msg).unwrap() { + Cw20QueryMsg::TokenInfo {} => { + let balances: &HashMap = + match self.token_querier.balances.get(contract_addr) { + Some(balances) => balances, + None => { + return SystemResult::Err(SystemError::Unknown {}); + } + }; + + let mut total_supply = Uint128::zero(); + + for balance in balances { + total_supply += *balance.1; + } + + SystemResult::Ok( + to_json_binary(&TokenInfoResponse { + name: "mAPPL".to_string(), + symbol: "mAPPL".to_string(), + decimals: 6, + total_supply, + }) + .into(), + ) + } + Cw20QueryMsg::Balance { address } => { + let balances: &HashMap = + match self.token_querier.balances.get(contract_addr) { + Some(balances) => balances, + None => { + return SystemResult::Err(SystemError::Unknown {}); + } + }; + + let balance = match balances.get(&address) { + Some(v) => v, + None => { + return SystemResult::Err(SystemError::Unknown {}); + } + }; + + SystemResult::Ok( + to_json_binary(&BalanceResponse { balance: *balance }).into(), + ) + } + _ => panic!("DO NOT ENTER HERE"), + } + } + } + QueryRequest::Wasm(WasmQuery::Raw { contract_addr, .. }) => { + if contract_addr == "factory" { + SystemResult::Ok(to_json_binary(&Vec::::new()).into()) + } else { + panic!("DO NOT ENTER HERE"); + } + } + _ => self.base.handle_query(request), + } + } +} + +impl SplitterMockQuerier { + pub fn new(base: MockQuerier) -> Self { + SplitterMockQuerier { + base, + token_querier: TokenQuerier::default(), + } + } + + // Configure the mint whitelist mock querier + pub fn with_token_balances(&mut self, balances: &[(&String, &[(&String, &Uint128)])]) { + self.token_querier = TokenQuerier::new(balances); + } + + pub fn with_balance(&mut self, balances: &[(&String, &[Coin])]) { + for (addr, balance) in balances { + self.base.update_balance(addr.to_string(), balance.to_vec()); + } + } +} diff --git a/packages/bindings-test/src/lib.rs b/packages/bindings-test/src/lib.rs index 9ea7c7b..38428bb 100644 --- a/packages/bindings-test/src/lib.rs +++ b/packages/bindings-test/src/lib.rs @@ -1,5 +1,6 @@ +mod coreum_testing_deps; mod multitest; -pub use multitest::{ - mock_coreum_deps, CoreumApp, CoreumAppWrapped, CoreumDeps, CoreumModule, BLOCK_TIME, -}; +pub use multitest::{CoreumApp, CoreumAppWrapped, CoreumModule, BLOCK_TIME}; + +pub use coreum_testing_deps::{mock_coreum_deps, CoreumDeps}; diff --git a/packages/bindings-test/src/multitest.rs b/packages/bindings-test/src/multitest.rs index 9881c44..33668a6 100644 --- a/packages/bindings-test/src/multitest.rs +++ b/packages/bindings-test/src/multitest.rs @@ -1,7 +1,6 @@ use std::{ cmp::max, fmt::Debug, - marker::PhantomData, ops::{Deref, DerefMut}, }; @@ -14,9 +13,9 @@ use coreum_wasm_sdk::{ core::{CoreumMsg, CoreumQueries}, }; use cosmwasm_std::{ - testing::{MockApi, MockQuerier, MockStorage}, + testing::{MockApi, MockStorage}, to_json_binary, Addr, Api, BalanceResponse, BankMsg, BankQuery, Binary, BlockInfo, CustomQuery, - Empty, OwnedDeps, Querier, QuerierWrapper, QueryRequest, Storage, + Empty, Querier, QuerierWrapper, QueryRequest, Storage, }; use cw_multi_test::{ App, AppResponse, BankKeeper, BankSudo, BasicAppBuilder, CosmosRouter, Module, WasmKeeper, @@ -26,17 +25,6 @@ use cw_multi_test::{ /// (when we increment block.height, use this multiplier for block.time) pub const BLOCK_TIME: u64 = 5; -pub type CoreumDeps = OwnedDeps; - -pub fn mock_coreum_deps() -> CoreumDeps { - CoreumDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: MockQuerier::default(), - custom_query_type: PhantomData, - } -} - pub struct CoreumModule {} impl Module for CoreumModule { From 0baa8b34a9e86220527f4afb116f928b6e1f08e5 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Thu, 1 Feb 2024 21:32:12 +0200 Subject: [PATCH 05/15] Fee splitter: updates the old tests with the proper way of testing style. Binding test: refactoring. --- contracts/fee_splitter/src/contract.rs | 2 +- contracts/fee_splitter/src/testing.rs | 98 +++++++------------ packages/bindings-test/src/lib.rs | 4 +- .../{coreum_testing_deps.rs => testing.rs} | 0 4 files changed, 37 insertions(+), 67 deletions(-) rename packages/bindings-test/src/{coreum_testing_deps.rs => testing.rs} (100%) diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index 3c28a48..d132f8a 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -34,7 +34,7 @@ pub fn instantiate( .iter() .map(|&(_, weight)| weight) .fold(Decimal::zero(), |acc, x| acc + x) - .le(&Decimal::from_ratio(1u32, 1u32)); + .le(&Decimal::percent(100u64)); if !is_weights_valid { return Err(ContractError::InvalidWeights {}); diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index a1d6c19..d871a17 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -1,76 +1,56 @@ -use bindings_test::{mock_coreum_deps, CoreumApp}; -use coreum_wasm_sdk::core::CoreumMsg; +use bindings_test::mock_coreum_deps; use cosmwasm_std::{ testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, - Addr, Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, + Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, }; -use cw_multi_test::{ContractWrapper, Executor}; use crate::{ - contract::{execute, instantiate}, - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, - state::Config, + contract::{execute, instantiate, SubMsg}, + error::ContractError, + msg::{ExecuteMsg, InstantiateMsg}, }; -pub type SubMsg = cosmwasm_std::SubMsg; - #[test] fn init_works() { - let mut app = CoreumApp::default(); - - let code_id = store_fee_splitter_code(&mut app); + let mut deps = mock_coreum_deps(&[]); + let env = mock_env(); let sender = "addr0000"; + let info = mock_info(sender, &[]); - let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(1u128, 2u128)); - let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(1u128, 2u128)); + let first_tupple = ("ATOM".to_string(), Decimal::percent(50u64)); + let second_tuple = ("TIA".to_string(), Decimal::percent(50u64)); let msg = InstantiateMsg { addresses: vec![first_tupple.clone(), second_tuple.clone()], - cw20_contracts: vec!["cw20_contract_one".to_string()], + cw20_contracts: vec!["USDT".to_string()], }; - let fee_splitter_instance = app - .instantiate_contract( - code_id, - Addr::unchecked(sender), - &msg, - &[], - "fee-splitter", - None, - ) - .unwrap(); - - let config_response: Config = app - .wrap() - .query_wasm_smart(fee_splitter_instance, &QueryMsg::Config {}) - .unwrap(); - - assert_eq!(config_response.addresses, vec![first_tupple, second_tuple]); + let res = instantiate(deps.as_mut(), env, info, msg).unwrap(); + + assert_eq!( + res.attributes, + vec![Attribute { + key: "initialized".to_string(), + value: "fee_splitter contract".to_string(), + }] + ); } #[test] -#[should_panic(expected = "Provided weights exceed maximum allowed value")] fn fails_to_init_because_weights_not_correct() { - let mut app = CoreumApp::default(); - - let code_id = store_fee_splitter_code(&mut app); + let mut deps = mock_coreum_deps(&[]); + let env = mock_env(); let sender = "addr0000"; + let info = mock_info(sender, &[]); - let first_tupple = ("tokenA".to_string(), Decimal::from_ratio(2u128, 1u128)); - let second_tuple = ("tokenB".to_string(), Decimal::from_ratio(2u128, 1u128)); + let first_tupple = ("ATOM".to_string(), Decimal::percent(50u64)); + let second_tuple = ("TIA".to_string(), Decimal::percent(60u64)); let msg = InstantiateMsg { addresses: vec![first_tupple.clone(), second_tuple.clone()], - cw20_contracts: vec!["cw20_contract_one".to_string()], + cw20_contracts: vec!["USDT".to_string()], }; - app.instantiate_contract( - code_id, - Addr::unchecked(sender), - &msg, - &[], - "fee-splitter", - None, - ) - .unwrap(); + let res = instantiate(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(res, ContractError::InvalidWeights {}); } #[test] @@ -82,11 +62,11 @@ fn should_send_tokens_in_correct_amount() { &[ Coin { denom: "ATOM".to_string(), - amount: Uint128::new(100_000000000000000000), + amount: Uint128::new(100_000), }, Coin { denom: "TIA".to_string(), - amount: Uint128::new(100_000000000000000000), + amount: Uint128::new(100_000), }, ], )]); @@ -130,11 +110,11 @@ fn should_send_tokens_in_correct_amount() { amount: vec![ Coin { denom: "ATOM".to_string(), - amount: Uint128::new(60000000000000000000), + amount: Uint128::new(60_000), }, Coin { denom: "TIA".to_string(), - amount: Uint128::new(60000000000000000000), + amount: Uint128::new(60_000), } ] }), @@ -148,11 +128,11 @@ fn should_send_tokens_in_correct_amount() { amount: vec![ Coin { denom: "ATOM".to_string(), - amount: Uint128::new(40000000000000000000), + amount: Uint128::new(40_000), }, Coin { denom: "TIA".to_string(), - amount: Uint128::new(40000000000000000000), + amount: Uint128::new(40_000), } ] }), @@ -162,13 +142,3 @@ fn should_send_tokens_in_correct_amount() { ] ); } - -fn store_fee_splitter_code(app: &mut CoreumApp) -> u64 { - let fee_splitter_contract = Box::new(ContractWrapper::new( - crate::contract::instantiate, - crate::contract::instantiate, - crate::contract::query, - )); - - app.store_code(fee_splitter_contract) -} diff --git a/packages/bindings-test/src/lib.rs b/packages/bindings-test/src/lib.rs index 38428bb..3fae80d 100644 --- a/packages/bindings-test/src/lib.rs +++ b/packages/bindings-test/src/lib.rs @@ -1,6 +1,6 @@ -mod coreum_testing_deps; mod multitest; +mod testing; pub use multitest::{CoreumApp, CoreumAppWrapped, CoreumModule, BLOCK_TIME}; -pub use coreum_testing_deps::{mock_coreum_deps, CoreumDeps}; +pub use testing::{mock_coreum_deps, CoreumDeps}; diff --git a/packages/bindings-test/src/coreum_testing_deps.rs b/packages/bindings-test/src/testing.rs similarity index 100% rename from packages/bindings-test/src/coreum_testing_deps.rs rename to packages/bindings-test/src/testing.rs From 9aa6504224359d7cd36770ac6cb0b1eb57e0debf Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Thu, 1 Feb 2024 21:36:02 +0200 Subject: [PATCH 06/15] Binding test: additional refactoring. --- packages/bindings-test/src/testing.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/bindings-test/src/testing.rs b/packages/bindings-test/src/testing.rs index ebffee6..bd9b8ed 100644 --- a/packages/bindings-test/src/testing.rs +++ b/packages/bindings-test/src/testing.rs @@ -14,11 +14,11 @@ use dex::factory::{ use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; -pub type CoreumDeps = OwnedDeps; +pub type CoreumDeps = OwnedDeps; pub fn mock_coreum_deps(contract_balance: &[Coin]) -> CoreumDeps { let custom_qurier = - SplitterMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + WhelpMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); CoreumDeps { storage: MockStorage::default(), @@ -28,7 +28,7 @@ pub fn mock_coreum_deps(contract_balance: &[Coin]) -> CoreumDeps { } } -pub struct SplitterMockQuerier { +pub struct WhelpMockQuerier { base: MockQuerier, token_querier: TokenQuerier, } @@ -61,7 +61,7 @@ pub(crate) fn balances_to_map( } balances_map } -impl Querier for SplitterMockQuerier { +impl Querier for WhelpMockQuerier { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { // MockQuerier doesn't support Custom, so we ignore it completely let request: QueryRequest = match from_json(bin_request) { @@ -77,7 +77,7 @@ impl Querier for SplitterMockQuerier { } } -impl SplitterMockQuerier { +impl WhelpMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { @@ -167,9 +167,9 @@ impl SplitterMockQuerier { } } -impl SplitterMockQuerier { +impl WhelpMockQuerier { pub fn new(base: MockQuerier) -> Self { - SplitterMockQuerier { + WhelpMockQuerier { base, token_querier: TokenQuerier::default(), } From d0037c5ed92444b3b198a6396a0b211048c67534 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Thu, 1 Feb 2024 21:45:04 +0200 Subject: [PATCH 07/15] Fee splitter: fixes minor test issues with missing info and wrong deps type. --- contracts/fee_splitter/src/testing.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index d871a17..0cbb2be 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -84,7 +84,7 @@ fn should_send_tokens_in_correct_amount() { cw20_contracts: vec![], }; - let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); + let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); assert_eq!( fee_splitter_instance.attributes, vec![Attribute { @@ -98,7 +98,7 @@ fn should_send_tokens_in_correct_amount() { cw20_addresses: vec!["cw20_contract_one".to_string()], }; - let res = execute(deps.as_ref(), env, msg).unwrap(); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( res.messages, From b504b7c0a169b51a367ab1488befde6aced2fcab Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 13:17:52 +0200 Subject: [PATCH 08/15] fee-splitter: fixes wrong type of info provided --- contracts/fee_splitter/src/testing.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 0cbb2be..545fbdb 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -17,10 +17,10 @@ fn init_works() { let sender = "addr0000"; let info = mock_info(sender, &[]); - let first_tupple = ("ATOM".to_string(), Decimal::percent(50u64)); - let second_tuple = ("TIA".to_string(), Decimal::percent(50u64)); + let first_addr_pecnt = ("address0000".to_string(), Decimal::percent(50u64)); + let second_addr_pecnt = ("address0001".to_string(), Decimal::percent(50u64)); let msg = InstantiateMsg { - addresses: vec![first_tupple.clone(), second_tuple.clone()], + addresses: vec![first_addr_pecnt.clone(), second_addr_pecnt.clone()], cw20_contracts: vec!["USDT".to_string()], }; From 237925036d2f561c2e3f7568be5276b1a136668e Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 14:45:29 +0200 Subject: [PATCH 09/15] fee-splitter: adds a 2nd assertion to a test --- contracts/fee_splitter/src/testing.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 545fbdb..1ef4d34 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -1,13 +1,15 @@ use bindings_test::mock_coreum_deps; use cosmwasm_std::{ + from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, }; use crate::{ - contract::{execute, instantiate, SubMsg}, + contract::{execute, instantiate, query, SubMsg}, error::ContractError, - msg::{ExecuteMsg, InstantiateMsg}, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + state::Config, }; #[test] @@ -98,7 +100,7 @@ fn should_send_tokens_in_correct_amount() { cw20_addresses: vec!["cw20_contract_one".to_string()], }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); assert_eq!( res.messages, @@ -141,4 +143,18 @@ fn should_send_tokens_in_correct_amount() { }, ] ); + + let msg = QueryMsg::Config {}; + + let query_result = query(deps.as_ref(), env, msg).unwrap(); + let config_res: Config = from_json(query_result).unwrap(); + assert_eq!( + config_res, + Config { + addresses: vec![ + ("address0000".to_string(), Decimal::percent(60)), + ("address0001".to_string(), Decimal::percent(40)) + ], + } + ); } From e23d2f1262d908454591ed4c72419f9daa2e3f72 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 18:33:30 +0200 Subject: [PATCH 10/15] fee-splitter: extends the tests --- contracts/fee_splitter/src/testing.rs | 46 +++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 1ef4d34..4e2512d 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -2,8 +2,9 @@ use bindings_test::mock_coreum_deps; use cosmwasm_std::{ from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, - Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, + Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, WasmMsg, to_json_binary, }; +use cw20::Cw20ExecuteMsg; use crate::{ contract::{execute, instantiate, query, SubMsg}, @@ -59,6 +60,17 @@ fn fails_to_init_because_weights_not_correct() { fn should_send_tokens_in_correct_amount() { let mut deps = mock_coreum_deps(&[]); + deps.querier.with_token_balances(&[ + ( + &String::from("liquidity0000"), + &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], + ), + ( + &String::from("asset0000"), + &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], + ), + ]); + deps.querier.with_balance(&[( &String::from(MOCK_CONTRACT_ADDR), &[ @@ -83,10 +95,11 @@ fn should_send_tokens_in_correct_amount() { ("address0000".to_string(), Decimal::percent(60u64)), ("address0001".to_string(), Decimal::percent(40u64)), ], - cw20_contracts: vec![], + cw20_contracts: vec!["asset0000".to_string(), "asset0001".to_string()], }; let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + assert_eq!( fee_splitter_instance.attributes, vec![Attribute { @@ -97,7 +110,7 @@ fn should_send_tokens_in_correct_amount() { let msg = ExecuteMsg::SendTokens { native_denoms: vec!["ATOM".to_string(), "TIA".to_string()], - cw20_addresses: vec!["cw20_contract_one".to_string()], + cw20_addresses: vec!["asset0000".to_string()], }; let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -123,6 +136,19 @@ fn should_send_tokens_in_correct_amount() { gas_limit: None, reply_on: ReplyOn::Never }, + SubMsg { + id: 0, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "asset0000".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: "address0000".to_string(), + amount: Uint128::new(60_000), + }).unwrap(), + funds: vec![] + }), + gas_limit: None, + reply_on: ReplyOn::Never + }, SubMsg { id: 0, msg: CosmosMsg::Bank(BankMsg::Send { @@ -141,6 +167,19 @@ fn should_send_tokens_in_correct_amount() { gas_limit: None, reply_on: ReplyOn::Never }, + SubMsg { + id: 0, + msg: CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "asset0000".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: "address0001".to_string(), + amount: Uint128::new(40_000), + }).unwrap(), + funds: vec![] + }), + gas_limit: None, + reply_on: ReplyOn::Never + }, ] ); @@ -148,6 +187,7 @@ fn should_send_tokens_in_correct_amount() { let query_result = query(deps.as_ref(), env, msg).unwrap(); let config_res: Config = from_json(query_result).unwrap(); + assert_eq!( config_res, Config { From 1e5511c14fee45b2820e8e6ce24cd9125a26bf4f Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 18:38:25 +0200 Subject: [PATCH 11/15] fee-splitter: fmt --- contracts/fee_splitter/src/testing.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 4e2512d..0a81dfd 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -2,7 +2,7 @@ use bindings_test::mock_coreum_deps; use cosmwasm_std::{ from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, - Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, WasmMsg, to_json_binary, + to_json_binary, Attribute, BankMsg, Coin, CosmosMsg, Decimal, ReplyOn, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; @@ -143,7 +143,8 @@ fn should_send_tokens_in_correct_amount() { msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "address0000".to_string(), amount: Uint128::new(60_000), - }).unwrap(), + }) + .unwrap(), funds: vec![] }), gas_limit: None, @@ -174,7 +175,8 @@ fn should_send_tokens_in_correct_amount() { msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "address0001".to_string(), amount: Uint128::new(40_000), - }).unwrap(), + }) + .unwrap(), funds: vec![] }), gas_limit: None, From 18db092704fe3fba92b1da4b2eeedcafcf80f999 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 20:13:31 +0200 Subject: [PATCH 12/15] fee-splitter: removes unnecessary mock --- contracts/fee_splitter/src/testing.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 0a81dfd..d497575 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -61,10 +61,6 @@ fn should_send_tokens_in_correct_amount() { let mut deps = mock_coreum_deps(&[]); deps.querier.with_token_balances(&[ - ( - &String::from("liquidity0000"), - &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], - ), ( &String::from("asset0000"), &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], From 3b18ad1cd1028dc11740e74a3247d676b618c9c2 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 20:15:17 +0200 Subject: [PATCH 13/15] fee-splitter: fmt --- contracts/fee_splitter/src/testing.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index d497575..763d702 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -60,12 +60,10 @@ fn fails_to_init_because_weights_not_correct() { fn should_send_tokens_in_correct_amount() { let mut deps = mock_coreum_deps(&[]); - deps.querier.with_token_balances(&[ - ( - &String::from("asset0000"), - &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], - ), - ]); + deps.querier.with_token_balances(&[( + &String::from("asset0000"), + &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], + )]); deps.querier.with_balance(&[( &String::from(MOCK_CONTRACT_ADDR), From b0117a195b0dff31d470f2991808be2c1a475a91 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Fri, 2 Feb 2024 21:43:56 +0200 Subject: [PATCH 14/15] fee-splitter: adds consts instead of writing the same vars in each test --- contracts/fee_splitter/src/testing.rs | 75 ++++++++++++++------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 763d702..4c8bbd6 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -13,18 +13,26 @@ use crate::{ state::Config, }; +const SENDER: &str = "addr0000"; +const FIRST_RECIPIENT: &str = "address0000"; +const SECOND_RECIPIENT: &str = "address0001"; +const ATOM: &str = "ATOM"; +const TIA: &str = "TIA"; +const USDT: &str = "USDT"; +const CW20_ASSET_ONE: &str = "asset0000"; +const CW20_ASSET_TWO: &str = "asset0001"; + #[test] fn init_works() { let mut deps = mock_coreum_deps(&[]); let env = mock_env(); - let sender = "addr0000"; - let info = mock_info(sender, &[]); + let info = mock_info(SENDER, &[]); - let first_addr_pecnt = ("address0000".to_string(), Decimal::percent(50u64)); - let second_addr_pecnt = ("address0001".to_string(), Decimal::percent(50u64)); + let first_addr_percent = (FIRST_RECIPIENT.to_string(), Decimal::percent(50u64)); + let second_addr_percent = (SECOND_RECIPIENT.to_string(), Decimal::percent(50u64)); let msg = InstantiateMsg { - addresses: vec![first_addr_pecnt.clone(), second_addr_pecnt.clone()], - cw20_contracts: vec!["USDT".to_string()], + addresses: vec![first_addr_percent.clone(), second_addr_percent.clone()], + cw20_contracts: vec![USDT.to_string()], }; let res = instantiate(deps.as_mut(), env, info, msg).unwrap(); @@ -42,14 +50,13 @@ fn init_works() { fn fails_to_init_because_weights_not_correct() { let mut deps = mock_coreum_deps(&[]); let env = mock_env(); - let sender = "addr0000"; - let info = mock_info(sender, &[]); + let info = mock_info(SENDER, &[]); - let first_tupple = ("ATOM".to_string(), Decimal::percent(50u64)); - let second_tuple = ("TIA".to_string(), Decimal::percent(60u64)); + let first_addr_percent = (FIRST_RECIPIENT.to_string(), Decimal::percent(50u64)); + let second_addr_percent = (SECOND_RECIPIENT.to_string(), Decimal::percent(60u64)); let msg = InstantiateMsg { - addresses: vec![first_tupple.clone(), second_tuple.clone()], - cw20_contracts: vec!["USDT".to_string()], + addresses: vec![first_addr_percent.clone(), second_addr_percent.clone()], + cw20_contracts: vec![USDT.to_string()], }; let res = instantiate(deps.as_mut(), env, info, msg).unwrap_err(); @@ -61,7 +68,7 @@ fn should_send_tokens_in_correct_amount() { let mut deps = mock_coreum_deps(&[]); deps.querier.with_token_balances(&[( - &String::from("asset0000"), + &String::from(CW20_ASSET_ONE), &[(&String::from(MOCK_CONTRACT_ADDR), &Uint128::new(100_000))], )]); @@ -69,11 +76,11 @@ fn should_send_tokens_in_correct_amount() { &String::from(MOCK_CONTRACT_ADDR), &[ Coin { - denom: "ATOM".to_string(), + denom: ATOM.to_string(), amount: Uint128::new(100_000), }, Coin { - denom: "TIA".to_string(), + denom: TIA.to_string(), amount: Uint128::new(100_000), }, ], @@ -81,15 +88,13 @@ fn should_send_tokens_in_correct_amount() { let env = mock_env(); - let sender = "addr0000"; - - let info = mock_info(sender, &[]); + let info = mock_info(SENDER, &[]); let msg = InstantiateMsg { addresses: vec![ - ("address0000".to_string(), Decimal::percent(60u64)), - ("address0001".to_string(), Decimal::percent(40u64)), + (FIRST_RECIPIENT.to_string(), Decimal::percent(60u64)), + (SECOND_RECIPIENT.to_string(), Decimal::percent(40u64)), ], - cw20_contracts: vec!["asset0000".to_string(), "asset0001".to_string()], + cw20_contracts: vec![CW20_ASSET_ONE.to_string(), CW20_ASSET_TWO.to_string()], }; let fee_splitter_instance = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); @@ -103,8 +108,8 @@ fn should_send_tokens_in_correct_amount() { ); let msg = ExecuteMsg::SendTokens { - native_denoms: vec!["ATOM".to_string(), "TIA".to_string()], - cw20_addresses: vec!["asset0000".to_string()], + native_denoms: vec![ATOM.to_string(), TIA.to_string()], + cw20_addresses: vec![CW20_ASSET_ONE.to_string()], }; let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -115,14 +120,14 @@ fn should_send_tokens_in_correct_amount() { SubMsg { id: 0, msg: CosmosMsg::Bank(BankMsg::Send { - to_address: "address0000".to_string(), + to_address: FIRST_RECIPIENT.to_string(), amount: vec![ Coin { - denom: "ATOM".to_string(), + denom: ATOM.to_string(), amount: Uint128::new(60_000), }, Coin { - denom: "TIA".to_string(), + denom: TIA.to_string(), amount: Uint128::new(60_000), } ] @@ -133,9 +138,9 @@ fn should_send_tokens_in_correct_amount() { SubMsg { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "asset0000".to_string(), + contract_addr: CW20_ASSET_ONE.to_string(), msg: to_json_binary(&Cw20ExecuteMsg::Transfer { - recipient: "address0000".to_string(), + recipient: FIRST_RECIPIENT.to_string(), amount: Uint128::new(60_000), }) .unwrap(), @@ -147,14 +152,14 @@ fn should_send_tokens_in_correct_amount() { SubMsg { id: 0, msg: CosmosMsg::Bank(BankMsg::Send { - to_address: "address0001".to_string(), + to_address: SECOND_RECIPIENT.to_string(), amount: vec![ Coin { - denom: "ATOM".to_string(), + denom: ATOM.to_string(), amount: Uint128::new(40_000), }, Coin { - denom: "TIA".to_string(), + denom: TIA.to_string(), amount: Uint128::new(40_000), } ] @@ -165,9 +170,9 @@ fn should_send_tokens_in_correct_amount() { SubMsg { id: 0, msg: CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "asset0000".to_string(), + contract_addr: CW20_ASSET_ONE.to_string(), msg: to_json_binary(&Cw20ExecuteMsg::Transfer { - recipient: "address0001".to_string(), + recipient: SECOND_RECIPIENT.to_string(), amount: Uint128::new(40_000), }) .unwrap(), @@ -188,8 +193,8 @@ fn should_send_tokens_in_correct_amount() { config_res, Config { addresses: vec![ - ("address0000".to_string(), Decimal::percent(60)), - ("address0001".to_string(), Decimal::percent(40)) + (FIRST_RECIPIENT.to_string(), Decimal::percent(60)), + (SECOND_RECIPIENT.to_string(), Decimal::percent(40)) ], } ); From a34da597cf06d7134f604e9f42330b8d1cb36898 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov Date: Mon, 5 Feb 2024 17:16:11 +0200 Subject: [PATCH 15/15] fee-splitter: changes the contract initialization and adds test for when the weights are below the limit --- contracts/fee_splitter/src/contract.rs | 2 +- contracts/fee_splitter/src/testing.rs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/contracts/fee_splitter/src/contract.rs b/contracts/fee_splitter/src/contract.rs index e5d5dd5..3fe199d 100644 --- a/contracts/fee_splitter/src/contract.rs +++ b/contracts/fee_splitter/src/contract.rs @@ -34,7 +34,7 @@ pub fn instantiate( .iter() .map(|&(_, weight)| weight) .fold(Decimal::zero(), |acc, x| acc + x) - .le(&Decimal::percent(100u64)); + .eq(&Decimal::percent(100u64)); if !is_weights_valid { return Err(ContractError::InvalidWeights {}); diff --git a/contracts/fee_splitter/src/testing.rs b/contracts/fee_splitter/src/testing.rs index 4c8bbd6..487c77e 100644 --- a/contracts/fee_splitter/src/testing.rs +++ b/contracts/fee_splitter/src/testing.rs @@ -47,7 +47,7 @@ fn init_works() { } #[test] -fn fails_to_init_because_weights_not_correct() { +fn fails_to_init_because_weights_above_limit() { let mut deps = mock_coreum_deps(&[]); let env = mock_env(); let info = mock_info(SENDER, &[]); @@ -63,6 +63,23 @@ fn fails_to_init_because_weights_not_correct() { assert_eq!(res, ContractError::InvalidWeights {}); } +#[test] +fn fails_to_init_because_weights_below_limit() { + let mut deps = mock_coreum_deps(&[]); + let env = mock_env(); + let info = mock_info(SENDER, &[]); + + let first_addr_percent = (FIRST_RECIPIENT.to_string(), Decimal::percent(20u64)); + let second_addr_percent = (SECOND_RECIPIENT.to_string(), Decimal::percent(20u64)); + let msg = InstantiateMsg { + addresses: vec![first_addr_percent.clone(), second_addr_percent.clone()], + cw20_contracts: vec![USDT.to_string()], + }; + + let res = instantiate(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(res, ContractError::InvalidWeights {}); +} + #[test] fn should_send_tokens_in_correct_amount() { let mut deps = mock_coreum_deps(&[]);