diff --git a/Cargo.lock b/Cargo.lock index b1e7d67d1..5a6158b68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -691,19 +691,15 @@ dependencies = [ "bech32", "cosmwasm-schema", "cosmwasm-std", - "cw-admin-factory", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", "cw20-base 1.1.2", "cw4 1.1.2", - "dao-dao-core 2.5.0", "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", "dao-testing", "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", "osmosis-test-tube", "thiserror", ] @@ -839,6 +835,7 @@ dependencies = [ "cw-multi-test", "cw20 1.1.2", "cw20-base 1.1.2", + "dao-testing", "thiserror", ] @@ -858,6 +855,7 @@ dependencies = [ "cw20-stake 2.5.0", "dao-dao-core 2.5.0", "dao-interface 2.5.0", + "dao-testing", "dao-voting-cw20-staked", "thiserror", ] @@ -978,6 +976,7 @@ dependencies = [ "cw2 1.1.2", "cw20 1.1.2", "cw20-base 1.1.2", + "dao-testing", "thiserror", "wynd-utils", ] @@ -1072,6 +1071,7 @@ dependencies = [ "cw2 1.1.2", "cw20 1.1.2", "cw20-base 1.1.2", + "dao-testing", "thiserror", ] @@ -1378,6 +1378,7 @@ dependencies = [ "cw20-base 1.1.2", "cw20-stake 0.2.6", "dao-hooks 2.5.0", + "dao-testing", "dao-voting 2.5.0", "thiserror", ] @@ -1400,6 +1401,7 @@ dependencies = [ "cw20-base 1.1.2", "cw20-stake 2.5.0", "dao-hooks 2.5.0", + "dao-testing", "stake-cw20-external-rewards", "thiserror", ] @@ -1418,6 +1420,7 @@ dependencies = [ "cw20 1.1.2", "cw20-base 1.1.2", "cw20-stake 2.5.0", + "dao-testing", "stake-cw20-reward-distributor", "thiserror", ] @@ -1690,6 +1693,7 @@ dependencies = [ "dao-dao-macros 2.5.0", "dao-interface 2.5.0", "dao-proposal-sudo", + "dao-testing", "dao-voting-cw20-balance", "thiserror", ] @@ -2054,6 +2058,7 @@ dependencies = [ "dao-hooks 2.5.0", "dao-interface 2.5.0", "dao-proposal-single 2.5.0", + "dao-testing", "dao-voting 2.5.0", "dao-voting-cw20-balance", "thiserror", @@ -2250,35 +2255,58 @@ dependencies = [ name = "dao-testing" version = "2.5.0" dependencies = [ + "btsg-ft-factory", "cosmwasm-schema", "cosmwasm-std", "cw-admin-factory", "cw-core", + "cw-fund-distributor", "cw-hooks 2.5.0", "cw-multi-test", + "cw-payroll-factory", "cw-proposal-single", + "cw-token-swap", "cw-tokenfactory-issuer", "cw-utils 1.0.3", "cw-vesting", "cw2 1.1.2", "cw20 1.1.2", "cw20-base 1.1.2", + "cw20-stake 0.2.6", "cw20-stake 2.5.0", + "cw20-stake-external-rewards", "cw4 1.1.2", "cw4-group 1.1.2", + "cw4-voting", "cw721-base 0.18.0", "cw721-roles", + "dao-dao-core 2.4.1", "dao-dao-core 2.5.0", + "dao-interface 2.4.1", "dao-interface 2.5.0", + "dao-migrator", + "dao-pre-propose-approval-single 2.4.1", + "dao-pre-propose-approval-single 2.5.0", + "dao-pre-propose-approver", + "dao-pre-propose-multiple 2.4.1", "dao-pre-propose-multiple 2.5.0", + "dao-pre-propose-single 2.4.1", "dao-pre-propose-single 2.5.0", "dao-proposal-condorcet", + "dao-proposal-hook-counter", + "dao-proposal-multiple 2.4.1", + "dao-proposal-multiple 2.5.0", + "dao-proposal-single 2.4.1", "dao-proposal-single 2.5.0", + "dao-proposal-sudo", + "dao-rewards-distributor", "dao-test-custom-factory", "dao-voting 0.1.0", + "dao-voting 2.4.1", "dao-voting 2.5.0", "dao-voting-cw20-balance", "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", "dao-voting-cw4 2.5.0", "dao-voting-cw721-roles", "dao-voting-cw721-staked", @@ -2290,6 +2318,7 @@ dependencies = [ "serde", "serde_json", "stake-cw20", + "stake-cw20-external-rewards", ] [[package]] @@ -2350,6 +2379,7 @@ dependencies = [ "cw20-base 1.1.2", "dao-dao-macros 2.5.0", "dao-interface 2.5.0", + "dao-testing", "thiserror", ] @@ -2368,6 +2398,7 @@ dependencies = [ "cw20-stake 2.5.0", "dao-dao-macros 2.5.0", "dao-interface 2.5.0", + "dao-testing", "dao-voting 2.5.0", "thiserror", ] @@ -2404,6 +2435,7 @@ dependencies = [ "cw4-group 1.1.2", "dao-dao-macros 2.5.0", "dao-interface 2.5.0", + "dao-testing", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 1d98d3a94..b5e2218bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,6 +85,7 @@ wynd-utils = "0.4" # optional owner. cw-ownable = "0.5" +btsg-ft-factory = { path = "./contracts/external/btsg-ft-factory", version = "2.5.0" } cw-admin-factory = { path = "./contracts/external/cw-admin-factory", version = "2.5.0" } cw-denom = { path = "./packages/cw-denom", version = "2.5.0" } cw-fund-distributor = { path = "./contracts/distribution/cw-fund-distributor", version = "2.5.0" } @@ -92,11 +93,13 @@ cw-hooks = { path = "./packages/cw-hooks", version = "2.5.0" } cw-paginate-storage = { path = "./packages/cw-paginate-storage", version = "2.5.0" } cw-payroll-factory = { path = "./contracts/external/cw-payroll-factory", version = "2.5.0" } cw-stake-tracker = { path = "./packages/cw-stake-tracker", version = "2.5.0" } +cw-token-swap = { path = "./contracts/external/cw-token-swap", version = "2.5.0" } cw-tokenfactory-issuer = { path = "./contracts/external/cw-tokenfactory-issuer", version = "2.5.0", default-features = false } cw-tokenfactory-types = { path = "./packages/cw-tokenfactory-types", version = "2.5.0", default-features = false } cw-vesting = { path = "./contracts/external/cw-vesting", version = "2.5.0" } cw-wormhole = { path = "./packages/cw-wormhole", version = "2.5.0" } cw20-stake = { path = "./contracts/staking/cw20-stake", version = "2.5.0" } +cw20-stake-external-rewards = { path = "./contracts/staking/cw20-stake-external-rewards", version = "2.5.0" } cw721-controllers = { path = "./packages/cw721-controllers", version = "2.5.0" } cw721-roles = { path = "./contracts/external/cw721-roles", version = "2.5.0" } dao-cw721-extensions = { path = "./packages/dao-cw721-extensions", version = "2.5.0" } @@ -104,6 +107,7 @@ dao-dao-core = { path = "./contracts/dao-dao-core", version = "2.5.0" } dao-dao-macros = { path = "./packages/dao-dao-macros", version = "2.5.0" } dao-hooks = { path = "./packages/dao-hooks", version = "2.5.0" } dao-interface = { path = "./packages/dao-interface", version = "2.5.0" } +dao-migrator = { path = "./contracts/external/dao-migrator", version = "2.5.0" } dao-pre-propose-approval-single = { path = "./contracts/pre-propose/dao-pre-propose-approval-single", version = "2.5.0" } dao-pre-propose-approver = { path = "./contracts/pre-propose/dao-pre-propose-approver", version = "2.5.0" } dao-pre-propose-base = { path = "./packages/dao-pre-propose-base", version = "2.5.0" } @@ -134,9 +138,12 @@ cw20-stake-external-rewards-v1 = { package = "stake-cw20-external-rewards", vers cw20-stake-reward-distributor-v1 = { package = "stake-cw20-reward-distributor", version = "0.1.0" } cw20-stake-v1 = { package = "cw20-stake", version = "0.2.6" } cw20-staked-balance-voting-v1 = { package = "cw20-staked-balance-voting", version = "0.1.0" } -cw4-voting-v1 = { package = "cw4-voting", version = "0.1.0" } stake-cw20-v03 = { package = "stake-cw20", version = "0.2.6" } +cw4-voting-v1 = { package = "cw4-voting", version = "0.1.0", git = "https://github.com/DA0-DA0/dao-contracts.git", tag = "v1.0.0" } +cw-core-interface-v1 = { package = "cw-core-interface", version = "0.1.0", git = "https://github.com/DA0-DA0/dao-contracts.git", tag = "v1.0.0" } voting-v1 = { package = "dao-voting", version = "0.1.0" } +cw20-v1 = { version = "0.13", package = "cw20" } +cw4-v1 = { version = "0.13", package = "cw4" } # v2.4.1 dependencies. used for state migrations. cw-denom-v241 = { package = "cw-denom", version = "=2.4.1" } diff --git a/contracts/dao-dao-core/Cargo.toml b/contracts/dao-dao-core/Cargo.toml index a9ac8dae6..407dd6d89 100644 --- a/contracts/dao-dao-core/Cargo.toml +++ b/contracts/dao-dao-core/Cargo.toml @@ -35,4 +35,5 @@ cw-multi-test = { workspace = true } cw20-base = { workspace = true } cw721-base = { workspace = true } dao-proposal-sudo = { workspace = true } +dao-testing = { workspace = true } dao-voting-cw20-balance = { workspace = true } diff --git a/contracts/dao-dao-core/src/tests.rs b/contracts/dao-dao-core/src/tests.rs index 81dd040cb..205000e3d 100644 --- a/contracts/dao-dao-core/src/tests.rs +++ b/contracts/dao-dao-core/src/tests.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ to_json_binary, Addr, CosmosMsg, Empty, Storage, Uint128, WasmMsg, }; use cw2::{set_contract_version, ContractVersion}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, Executor}; use cw_storage_plus::{Item, Map}; use cw_utils::{Duration, Expiration}; use dao_interface::{ @@ -17,6 +17,10 @@ use dao_interface::{ state::{Admin, Config, ModuleInstantiateInfo, ProposalModule, ProposalModuleStatus}, voting::{InfoResponse, VotingPowerAtHeightResponse}, }; +use dao_testing::contracts::{ + cw20_base_contract, cw721_base_contract, dao_dao_core_contract, dao_proposal_sudo_contract, + dao_voting_cw20_balance_contract, v1::cw_core_v1_contract, +}; use crate::{ contract::{derive_proposal_module_prefix, migrate, CONTRACT_NAME, CONTRACT_VERSION}, @@ -26,62 +30,6 @@ use crate::{ const CREATOR_ADDR: &str = "creator"; -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn cw721_contract() -> Box> { - let contract = ContractWrapper::new( - cw721_base::entry::execute, - cw721_base::entry::instantiate, - cw721_base::entry::query, - ); - Box::new(contract) -} - -fn sudo_proposal_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_sudo::contract::execute, - dao_proposal_sudo::contract::instantiate, - dao_proposal_sudo::contract::query, - ); - Box::new(contract) -} - -fn cw20_balances_voting() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_balance::contract::execute, - dao_voting_cw20_balance::contract::instantiate, - dao_voting_cw20_balance::contract::query, - ) - .with_reply(dao_voting_cw20_balance::contract::reply); - Box::new(contract) -} - -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -fn v1_cw_core_contract() -> Box> { - use cw_core_v1::contract; - let contract = ContractWrapper::new(contract::execute, contract::instantiate, contract::query) - .with_reply(contract::reply) - .with_migrate(contract::migrate); - Box::new(contract) -} - fn instantiate_gov(app: &mut App, code_id: u64, msg: InstantiateMsg) -> Addr { app.instantiate_contract( code_id, @@ -96,8 +44,8 @@ fn instantiate_gov(app: &mut App, code_id: u64, msg: InstantiateMsg) -> Addr { fn test_instantiate_with_n_gov_modules(n: usize) { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let gov_id = app.store_code(cw_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let cw20_instantiate = cw20_base::msg::InstantiateMsg { name: "DAO".to_string(), @@ -176,8 +124,8 @@ fn test_valid_instantiate() { #[should_panic(expected = "Error parsing into type cw20_base::msg::InstantiateMsg: Invalid type")] fn test_instantiate_with_submessage_failure() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let gov_id = app.store_code(cw_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let cw20_instantiate = cw20_base::msg::InstantiateMsg { name: "DAO".to_string(), @@ -239,8 +187,8 @@ makes wickedness." #[test] fn test_update_config() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -338,8 +286,8 @@ fn test_update_config() { fn test_swap_governance(swaps: Vec<(u32, u32)>) { let mut app = App::default(); - let propmod_id = app.store_code(sudo_proposal_contract()); - let core_id = app.store_code(cw_core_contract()); + let propmod_id = app.store_code(dao_proposal_sudo_contract()); + let core_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -517,8 +465,8 @@ fn test_swap_governance_bad() { #[test] fn test_removed_modules_can_not_execute() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -680,8 +628,8 @@ fn test_removed_modules_can_not_execute() { #[test] fn test_module_already_disabled() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -782,8 +730,8 @@ fn test_module_already_disabled() { #[test] fn test_swap_voting_module() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -888,8 +836,8 @@ fn test_unauthorized(app: &mut App, gov_addr: Addr, msg: ExecuteMsg) { #[test] fn test_permissions() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -972,10 +920,10 @@ fn test_permissions() { fn do_standard_instantiate(auto_add: bool, admin: Option) -> (Addr, App) { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let voting_id = app.store_code(cw20_balances_voting()); - let gov_id = app.store_code(cw_core_contract()); - let cw20_id = app.store_code(cw20_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -1689,10 +1637,10 @@ fn test_remove_missing_key() { #[test] fn test_list_items() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let voting_id = app.store_code(cw20_balances_voting()); - let gov_id = app.store_code(cw_core_contract()); - let cw20_id = app.store_code(cw20_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -1808,10 +1756,10 @@ fn test_list_items() { #[test] fn test_instantiate_with_items() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let voting_id = app.store_code(cw20_balances_voting()); - let gov_id = app.store_code(cw_core_contract()); - let cw20_id = app.store_code(cw20_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -1927,7 +1875,7 @@ fn test_instantiate_with_items() { fn test_cw20_receive_auto_add() { let (gov_addr, mut app) = do_standard_instantiate(true, None); - let cw20_id = app.store_code(cw20_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let another_cw20 = app .instantiate_contract( cw20_id, @@ -2074,7 +2022,7 @@ fn test_cw20_receive_auto_add() { fn test_cw20_receive_no_auto_add() { let (gov_addr, mut app) = do_standard_instantiate(false, None); - let cw20_id = app.store_code(cw20_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let another_cw20 = app .instantiate_contract( cw20_id, @@ -2159,7 +2107,7 @@ fn test_cw20_receive_no_auto_add() { fn test_cw721_receive() { let (gov_addr, mut app) = do_standard_instantiate(true, None); - let cw721_id = app.store_code(cw721_contract()); + let cw721_id = app.store_code(cw721_base_contract()); let cw721_addr = app .instantiate_contract( @@ -2289,7 +2237,7 @@ fn test_cw721_receive() { fn test_cw721_receive_no_auto_add() { let (gov_addr, mut app) = do_standard_instantiate(false, None); - let cw721_id = app.store_code(cw721_contract()); + let cw721_id = app.store_code(cw721_base_contract()); let cw721_addr = app .instantiate_contract( @@ -2651,10 +2599,10 @@ fn test_dump_state_proposal_modules() { #[test] fn test_migrate_from_compatible() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let voting_id = app.store_code(cw20_balances_voting()); - let gov_id = app.store_code(cw_core_contract()); - let cw20_id = app.store_code(cw20_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -2739,11 +2687,11 @@ fn test_migrate_from_beta() { use cw_core_v1 as v1; let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let voting_id = app.store_code(cw20_balances_voting()); - let core_id = app.store_code(cw_core_contract()); - let v1_core_id = app.store_code(v1_cw_core_contract()); - let cw20_id = app.store_code(cw20_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let v1_core_id = app.store_code(cw_core_v1_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let proposal_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), @@ -2953,8 +2901,8 @@ fn test_execute_stargate_msg() { #[test] fn test_module_prefixes() { let mut app = App::default(); - let govmod_id = app.store_code(sudo_proposal_contract()); - let gov_id = app.store_code(cw_core_contract()); + let govmod_id = app.store_code(dao_proposal_sudo_contract()); + let gov_id = app.store_code(dao_dao_core_contract()); let govmod_instantiate = dao_proposal_sudo::msg::InstantiateMsg { root: CREATOR_ADDR.to_string(), diff --git a/contracts/distribution/cw-fund-distributor/Cargo.toml b/contracts/distribution/cw-fund-distributor/Cargo.toml index f73aba4df..2167dcbe2 100644 --- a/contracts/distribution/cw-fund-distributor/Cargo.toml +++ b/contracts/distribution/cw-fund-distributor/Cargo.toml @@ -31,5 +31,6 @@ cw-paginate-storage = { workspace = true } [dev-dependencies] dao-dao-core = { workspace = true, features = ["library"] } +dao-testing = { workspace = true } cw-multi-test = { workspace = true } cw20-base = { workspace = true, features = ["library"] } diff --git a/contracts/distribution/cw-fund-distributor/src/testing/adversarial_tests.rs b/contracts/distribution/cw-fund-distributor/src/testing/adversarial_tests.rs index 8df033529..cc0e0c865 100644 --- a/contracts/distribution/cw-fund-distributor/src/testing/adversarial_tests.rs +++ b/contracts/distribution/cw-fund-distributor/src/testing/adversarial_tests.rs @@ -1,9 +1,13 @@ use crate::msg::ExecuteMsg::ClaimAll; use crate::msg::{ExecuteMsg, InstantiateMsg}; -use cosmwasm_std::{to_json_binary, Addr, Binary, Coin, Empty, Uint128}; +use cosmwasm_std::{to_json_binary, Addr, Binary, Coin, Uint128}; use cw20::{BalanceResponse, Cw20Coin}; -use cw_multi_test::{next_block, App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; use cw_utils::Duration; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, cw_fund_distributor_contract, + dao_voting_cw20_staked_contract, +}; const CREATOR_ADDR: &str = "creator"; const FEE_DENOM: &str = "ujuno"; @@ -13,44 +17,6 @@ struct BaseTest { distributor_address: Addr, } -fn distributor_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_staked::contract::execute, - dao_voting_cw20_staked::contract::instantiate, - dao_voting_cw20_staked::contract::query, - ) - .with_reply(dao_voting_cw20_staked::contract::reply); - Box::new(contract) -} - -fn cw20_staking_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - fn instantiate_cw20( app: &mut App, sender: Addr, @@ -58,7 +24,7 @@ fn instantiate_cw20( name: String, symbol: String, ) -> Addr { - let cw20_id = app.store_code(cw20_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let msg = cw20_base::msg::InstantiateMsg { name, symbol, @@ -74,10 +40,10 @@ fn instantiate_cw20( fn setup_test(initial_balances: Vec) -> BaseTest { let mut app = App::default(); - let distributor_id = app.store_code(distributor_contract()); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balances_voting_contract()); - let stake_cw20_id = app.store_code(cw20_staking_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let stake_cw20_id = app.store_code(cw20_stake_contract()); let voting_address = app .instantiate_contract( diff --git a/contracts/distribution/cw-fund-distributor/src/testing/tests.rs b/contracts/distribution/cw-fund-distributor/src/testing/tests.rs index f3269dd3f..bc2770942 100644 --- a/contracts/distribution/cw-fund-distributor/src/testing/tests.rs +++ b/contracts/distribution/cw-fund-distributor/src/testing/tests.rs @@ -3,9 +3,13 @@ use crate::msg::{ NativeEntitlementResponse, QueryMsg, TotalPowerResponse, VotingContractResponse, }; use crate::ContractError; -use cosmwasm_std::{to_json_binary, Addr, Binary, Coin, Empty, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, Binary, Coin, Uint128, WasmMsg}; use cw20::Cw20Coin; -use cw_multi_test::{next_block, App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, cw_fund_distributor_contract, + dao_voting_cw20_staked_contract, +}; use crate::msg::ExecuteMsg::{ClaimAll, ClaimCW20, ClaimNatives}; use crate::msg::QueryMsg::TotalPower; @@ -15,44 +19,6 @@ use cw_utils::Duration; const CREATOR_ADDR: &str = "creator"; const FEE_DENOM: &str = "ujuno"; -fn distributor_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_staked::contract::execute, - dao_voting_cw20_staked::contract::instantiate, - dao_voting_cw20_staked::contract::query, - ) - .with_reply(dao_voting_cw20_staked::contract::reply); - Box::new(contract) -} - -fn cw20_staking_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - struct BaseTest { app: App, distributor_address: Addr, @@ -61,10 +27,10 @@ struct BaseTest { fn setup_test(initial_balances: Vec) -> BaseTest { let mut app = App::default(); - let distributor_id = app.store_code(distributor_contract()); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balances_voting_contract()); - let stake_cw20_id = app.store_code(cw20_staking_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let stake_cw20_id = app.store_code(cw20_stake_contract()); let voting_address = app .instantiate_contract( @@ -196,7 +162,7 @@ pub fn mint_natives(app: &mut App, recipient: Addr, amount: Uint128) { .unwrap(); } -pub fn fund_distributor_contract_cw20( +pub fn fund_cw_fund_distributor_contract_cw20( app: &mut App, distributor_address: Addr, token_address: Addr, @@ -216,7 +182,7 @@ pub fn fund_distributor_contract_cw20( .unwrap(); } -pub fn fund_distributor_contract_natives( +pub fn fund_cw_fund_distributor_contract_natives( app: &mut App, distributor_address: Addr, amount: Uint128, @@ -237,7 +203,7 @@ pub fn fund_distributor_contract_natives( #[test] fn test_instantiate_fails_given_invalid_voting_contract_address() { let mut app = App::default(); - let distributor_id = app.store_code(distributor_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); let expected_error: ContractError = app .instantiate_contract( @@ -265,10 +231,10 @@ fn test_instantiate_fails_given_invalid_voting_contract_address() { #[test] fn test_instantiate_fails_zero_voting_power() { let mut app = App::default(); - let distributor_id = app.store_code(distributor_contract()); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balances_voting_contract()); - let stake_cw20_id = app.store_code(cw20_staking_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let stake_cw20_id = app.store_code(cw20_stake_contract()); let initial_balances = vec![Cw20Coin { address: "bekauz".to_string(), @@ -376,7 +342,7 @@ fn test_fund_cw20() { let first_fund_amount = Uint128::new(20000); // fund the contract for the first time - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -391,7 +357,7 @@ fn test_fund_cw20() { let second_fund_amount = amount.checked_sub(first_fund_amount).unwrap(); // fund the remaining part - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -464,7 +430,7 @@ pub fn test_fund_natives() { let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -476,7 +442,7 @@ pub fn test_fund_natives() { // fund again with an existing balance with an existing balance, fund mint_natives(&mut app, Addr::unchecked("bekauz"), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -571,7 +537,7 @@ pub fn test_claim_cw20() { ); // fund the contract - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -641,7 +607,7 @@ pub fn test_claim_cw20_twice() { ); // fund the contract - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -715,7 +681,7 @@ pub fn test_claim_cw20s_empty_list() { ); // fund the contract - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address, @@ -760,7 +726,7 @@ pub fn test_claim_natives_twice() { let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -823,7 +789,7 @@ pub fn test_claim_natives() { let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -876,7 +842,7 @@ pub fn test_claim_all() { let amount = Uint128::new(500000); // mint and fund the distributor with native & cw20 tokens mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -889,7 +855,7 @@ pub fn test_claim_all() { amount, Addr::unchecked(CREATOR_ADDR), ); - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -956,7 +922,7 @@ pub fn test_claim_natives_empty_list_of_denoms() { let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1002,11 +968,11 @@ pub fn test_redistribute_unclaimed_funds() { amount: Uint128::new(20), }, ]); - let distributor_id = app.store_code(distributor_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1103,14 +1069,14 @@ pub fn test_unauthorized_redistribute_unclaimed_funds() { mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, Addr::unchecked(CREATOR_ADDR), ); - let distributor_id = app.store_code(distributor_contract()); + let distributor_id = app.store_code(cw_fund_distributor_contract()); let migrate_msg = &MigrateMsg::RedistributeUnclaimedFunds { distribution_height: app.block_info().height, }; @@ -1149,7 +1115,7 @@ pub fn test_claim_cw20_during_funding_period() { ); // fund the contract - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -1197,7 +1163,7 @@ pub fn test_claim_natives_during_funding_period() { mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); // fund the contract - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1241,7 +1207,7 @@ pub fn test_claim_all_during_funding_period() { let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1377,7 +1343,7 @@ fn test_query_cw20_entitlements() { amount, Addr::unchecked(CREATOR_ADDR), ); - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -1431,7 +1397,7 @@ fn test_query_native_entitlements() { // fund the contract with some native tokens let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1476,7 +1442,7 @@ fn test_query_cw20_entitlement() { amount, Addr::unchecked(CREATOR_ADDR), ); - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address.clone(), @@ -1539,7 +1505,7 @@ fn test_query_native_entitlement() { // fund the contract with some native tokens let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, @@ -1585,7 +1551,7 @@ fn test_query_cw20_tokens() { amount, Addr::unchecked(CREATOR_ADDR), ); - fund_distributor_contract_cw20( + fund_cw_fund_distributor_contract_cw20( &mut app, distributor_address.clone(), token_address, @@ -1628,7 +1594,7 @@ fn test_query_native_denoms() { // mint and fund the distributor with a native token let amount = Uint128::new(500000); mint_natives(&mut app, Addr::unchecked(CREATOR_ADDR), amount); - fund_distributor_contract_natives( + fund_cw_fund_distributor_contract_natives( &mut app, distributor_address.clone(), amount, diff --git a/contracts/distribution/dao-rewards-distributor/src/testing/mod.rs b/contracts/distribution/dao-rewards-distributor/src/testing/mod.rs index e84477456..f523b7235 100644 --- a/contracts/distribution/dao-rewards-distributor/src/testing/mod.rs +++ b/contracts/distribution/dao-rewards-distributor/src/testing/mod.rs @@ -1,6 +1,3 @@ -use cosmwasm_std::Empty; -use cw_multi_test::{Contract, ContractWrapper}; - pub mod suite; pub mod tests; @@ -12,15 +9,6 @@ pub const ADDR2: &str = "addr2"; pub const ADDR3: &str = "addr3"; pub const ADDR4: &str = "addr4"; -pub fn contract_rewards() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - mod cw4_setup { use cosmwasm_std::Addr; use cw4::Member; @@ -66,7 +54,7 @@ mod cw4_setup { mod native_setup { use cosmwasm_std::{coins, Addr}; use cw_multi_test::{App, Executor}; - use dao_testing::contracts::native_staked_balances_voting_contract; + use dao_testing::contracts::dao_voting_token_staked_contract; use super::{DENOM, OWNER}; @@ -100,7 +88,7 @@ mod native_setup { } pub fn setup_native_token_test(app: &mut App) -> Addr { - let vp_code_id = app.store_code(native_staked_balances_voting_contract()); + let vp_code_id = app.store_code(dao_voting_token_staked_contract()); let msg = dao_voting_token_staked::msg::InstantiateMsg { active_threshold: None, @@ -128,7 +116,7 @@ mod cw20_setup { use cw_multi_test::{App, Executor}; use cw_utils::Duration; use dao_testing::contracts::{ - cw20_base_contract, cw20_stake_contract, cw20_staked_balances_voting_contract, + cw20_base_contract, cw20_stake_contract, dao_voting_cw20_staked_contract, }; use super::OWNER; @@ -171,7 +159,7 @@ mod cw20_setup { } pub fn instantiate_cw20_vp_contract(app: &mut App, cw20: Addr, staking_contract: Addr) -> Addr { - let vp_code_id = app.store_code(cw20_staked_balances_voting_contract()); + let vp_code_id = app.store_code(dao_voting_cw20_staked_contract()); let msg = dao_voting_cw20_staked::msg::InstantiateMsg { token_info: dao_voting_cw20_staked::msg::TokenInfo::Existing { address: cw20.to_string(), @@ -220,7 +208,7 @@ mod cw721_setup { use cosmwasm_std::{to_json_binary, Addr, Binary, Empty}; use cw_multi_test::{App, Executor}; - use dao_testing::contracts::{cw721_base_contract, cw721_staked_voting_contract}; + use dao_testing::contracts::{cw721_base_contract, dao_voting_cw721_staked_contract}; use dao_voting_cw721_staked::state::Config; use super::OWNER; @@ -256,7 +244,7 @@ mod cw721_setup { pub fn setup_cw721_test(app: &mut App, initial_nfts: Vec) -> (Addr, Addr) { let cw721_code_id = app.store_code(cw721_base_contract()); - let vp_code_id = app.store_code(cw721_staked_voting_contract()); + let vp_code_id = app.store_code(dao_voting_cw721_staked_contract()); let msg = dao_voting_cw721_staked::msg::InstantiateMsg { nft_contract: dao_voting_cw721_staked::msg::NftContract::New { diff --git a/contracts/distribution/dao-rewards-distributor/src/testing/suite.rs b/contracts/distribution/dao-rewards-distributor/src/testing/suite.rs index ed01a2256..c0c1b41ec 100644 --- a/contracts/distribution/dao-rewards-distributor/src/testing/suite.rs +++ b/contracts/distribution/dao-rewards-distributor/src/testing/suite.rs @@ -8,6 +8,7 @@ use cw_multi_test::{App, BankSudo, Executor, SudoMsg}; use cw_ownable::Action; use cw_utils::Duration; use dao_interface::voting::InfoResponse; +use dao_testing::contracts::dao_rewards_distributor_contract; use crate::{ msg::{ @@ -20,7 +21,6 @@ use crate::{ }; use super::{ - contract_rewards, cw20_setup::{self, setup_cw20_test}, cw4_setup::setup_cw4_test, cw721_setup::{setup_cw721_test, stake_cw721, unstake_cw721}, @@ -230,7 +230,10 @@ impl SuiteBuilder { }; // initialize the rewards distributor - suite_built.reward_code_id = suite_built.app.borrow_mut().store_code(contract_rewards()); + suite_built.reward_code_id = suite_built + .app + .borrow_mut() + .store_code(dao_rewards_distributor_contract()); let reward_addr = suite_built .app .borrow_mut() diff --git a/contracts/external/btsg-ft-factory/src/testing/mod.rs b/contracts/external/btsg-ft-factory/src/testing/mod.rs index 2282ac98d..53e84f356 100644 --- a/contracts/external/btsg-ft-factory/src/testing/mod.rs +++ b/contracts/external/btsg-ft-factory/src/testing/mod.rs @@ -3,26 +3,15 @@ mod bitsong_stargate; mod tests; use app::BitsongApp; -use cosmwasm_std::{Addr, Empty}; -use cw_multi_test::{Contract, ContractWrapper, Executor}; -use dao_testing::contracts::native_staked_balances_voting_contract; +use cosmwasm_std::Addr; +use cw_multi_test::Executor; +use dao_testing::contracts::{btsg_ft_factory_contract, dao_voting_token_staked_contract}; use crate::msg::InstantiateMsg; /// Address used to stake stuff. pub(crate) const STAKER: &str = "staker"; -pub(crate) fn btsg_ft_factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - pub(crate) struct CommonTest { app: BitsongApp, module_id: u64, @@ -32,7 +21,7 @@ pub(crate) struct CommonTest { pub(crate) fn setup_test() -> CommonTest { let mut app = BitsongApp::new(); let factory_id = app.store_code(btsg_ft_factory_contract()); - let module_id = app.store_code(native_staked_balances_voting_contract()); + let module_id = app.store_code(dao_voting_token_staked_contract()); let factory = app .instantiate_contract( diff --git a/contracts/external/btsg-ft-factory/src/testing/tests.rs b/contracts/external/btsg-ft-factory/src/testing/tests.rs index 21cb4f58a..02d456659 100644 --- a/contracts/external/btsg-ft-factory/src/testing/tests.rs +++ b/contracts/external/btsg-ft-factory/src/testing/tests.rs @@ -9,7 +9,7 @@ use dao_interface::{ state::{Admin, ModuleInstantiateInfo}, token::InitialBalance, }; -use dao_testing::contracts::{dao_dao_contract, proposal_single_contract}; +use dao_testing::contracts::{dao_dao_core_contract, dao_proposal_single_contract}; use crate::{ bitsong::{Coin, MsgMint, MsgSetUri}, @@ -30,8 +30,8 @@ fn test_issue_fantoken() -> anyhow::Result<()> { .. } = setup_test(); - let core_id = app.store_code(dao_dao_contract()); - let proposal_single_id = app.store_code(proposal_single_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let proposal_single_id = app.store_code(dao_proposal_single_contract()); let initial_balances = vec![InitialBalance { amount: Uint128::new(100), @@ -132,8 +132,8 @@ fn test_initial_fantoken_balances() -> anyhow::Result<()> { .. } = setup_test(); - let core_id = app.store_code(dao_dao_contract()); - let proposal_single_id = app.store_code(proposal_single_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let proposal_single_id = app.store_code(dao_proposal_single_contract()); let initial_balances = vec![InitialBalance { amount: Uint128::new(100), @@ -239,8 +239,8 @@ fn test_fantoken_minter_and_authority_set_to_dao() -> anyhow::Result<()> { .. } = setup_test(); - let core_id = app.store_code(dao_dao_contract()); - let proposal_single_id = app.store_code(proposal_single_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let proposal_single_id = app.store_code(dao_proposal_single_contract()); let initial_balances = vec![InitialBalance { amount: Uint128::new(100), @@ -396,8 +396,8 @@ fn test_fantoken_can_be_staked() -> anyhow::Result<()> { .. } = setup_test(); - let core_id = app.store_code(dao_dao_contract()); - let proposal_single_id = app.store_code(proposal_single_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let proposal_single_id = app.store_code(dao_proposal_single_contract()); let initial_balances = vec![InitialBalance { amount: Uint128::new(100), diff --git a/contracts/external/cw-admin-factory/Cargo.toml b/contracts/external/cw-admin-factory/Cargo.toml index 394f859fb..3fc9fea98 100644 --- a/contracts/external/cw-admin-factory/Cargo.toml +++ b/contracts/external/cw-admin-factory/Cargo.toml @@ -32,14 +32,10 @@ cw-utils = { workspace = true } [dev-dependencies] bech32 = { workspace = true } cosmwasm-schema = { workspace = true } -cw-admin-factory = { workspace = true } cw-multi-test = { workspace = true } -cw20-base = { workspace = true, features = ["library"] } +cw20-base = { workspace = true } cw4 = { workspace = true } -dao-dao-core = { workspace = true, features = ["library"] } dao-interface = { workspace = true } -dao-proposal-single = { workspace = true } dao-testing = { workspace = true } dao-voting = { workspace = true } -dao-voting-cw4 = { workspace = true } osmosis-test-tube = { workspace = true } diff --git a/contracts/external/cw-admin-factory/src/tests.rs b/contracts/external/cw-admin-factory/src/tests.rs index 7e6dbfbed..b449e7353 100644 --- a/contracts/external/cw-admin-factory/src/tests.rs +++ b/contracts/external/cw-admin-factory/src/tests.rs @@ -2,11 +2,13 @@ use std::vec; use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, + to_json_binary, Addr, Binary, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, }; - -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, AppResponse, Executor}; use dao_interface::state::{Admin, ModuleInstantiateInfo}; +use dao_testing::contracts::{ + cw20_base_contract, cw_admin_factory_contract, dao_dao_core_contract, +}; use crate::{ contract::{ @@ -18,41 +20,11 @@ use crate::{ const ADMIN_ADDR: &str = "admin"; -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} - #[test] pub fn test_set_self_admin() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); + let code_id = app.store_code(cw_admin_factory_contract()); + let cw20_code_id = app.store_code(cw20_base_contract()); let cw20_instantiate = cw20_base::msg::InstantiateMsg { name: "DAO".to_string(), symbol: "DAO".to_string(), @@ -75,7 +47,7 @@ pub fn test_set_self_admin() { .unwrap(); // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); + let cw_core_code_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { dao_uri: None, admin: None, @@ -136,8 +108,8 @@ pub fn test_set_self_admin() { #[test] pub fn test_authorized_set_self_admin() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); + let code_id = app.store_code(cw_admin_factory_contract()); + let cw20_code_id = app.store_code(cw20_base_contract()); let cw20_instantiate = cw20_base::msg::InstantiateMsg { name: "DAO".to_string(), symbol: "DAO".to_string(), @@ -169,7 +141,7 @@ pub fn test_authorized_set_self_admin() { assert_eq!(current_admin.admin, Some(Addr::unchecked(ADMIN_ADDR))); // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); + let cw_core_code_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { dao_uri: None, admin: None, diff --git a/contracts/external/cw-payroll-factory/Cargo.toml b/contracts/external/cw-payroll-factory/Cargo.toml index 9b89969a5..94f43a37d 100644 --- a/contracts/external/cw-payroll-factory/Cargo.toml +++ b/contracts/external/cw-payroll-factory/Cargo.toml @@ -1,5 +1,5 @@ [package] -name ="cw-payroll-factory" +name = "cw-payroll-factory" authors = ["Jake Hartnell"] description = "A CosmWasm factory contract for instantiating a payroll contract." edition = { workspace = true } @@ -31,4 +31,5 @@ cw-utils = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } cw20-base = { workspace = true, features = ["library"] } +dao-testing = { workspace = true } wynd-utils = { workspace = true } diff --git a/contracts/external/cw-payroll-factory/src/tests.rs b/contracts/external/cw-payroll-factory/src/tests.rs index 1feffd463..23f2bade1 100644 --- a/contracts/external/cw-payroll-factory/src/tests.rs +++ b/contracts/external/cw-payroll-factory/src/tests.rs @@ -1,12 +1,15 @@ -use cosmwasm_std::{coins, to_json_binary, Addr, Empty, Uint128}; +use cosmwasm_std::{coins, to_json_binary, Addr, Uint128}; use cw20::{Cw20Coin, Cw20ExecuteMsg}; use cw_denom::UncheckedDenom; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{App, BankSudo, Executor, SudoMsg}; use cw_ownable::OwnershipError; use cw_vesting::{ msg::{InstantiateMsg as PayrollInstantiateMsg, QueryMsg as PayrollQueryMsg}, vesting::{Schedule, Status, Vest}, }; +use dao_testing::contracts::{ + cw20_base_contract, cw_payroll_factory_contract, cw_vesting_contract, +}; use crate::{ msg::{ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg}, @@ -19,38 +22,10 @@ const BOB: &str = "bob"; const INITIAL_BALANCE: u128 = 1000000000; const NATIVE_DENOM: &str = "denom"; -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -pub fn cw_vesting_contract() -> Box> { - let contract = ContractWrapper::new( - cw_vesting::contract::execute, - cw_vesting::contract::instantiate, - cw_vesting::contract::query, - ); - Box::new(contract) -} - #[test] pub fn test_instantiate_native_payroll_contract() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); + let code_id = app.store_code(cw_payroll_factory_contract()); let cw_vesting_code_id = app.store_code(cw_vesting_contract()); // Instantiate factory with only Alice allowed to instantiate payroll contracts @@ -211,8 +186,8 @@ pub fn test_instantiate_native_payroll_contract() { #[test] pub fn test_instantiate_cw20_payroll_contract() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); + let code_id = app.store_code(cw_payroll_factory_contract()); + let cw20_code_id = app.store_code(cw20_base_contract()); let cw_vesting_code_id = app.store_code(cw_vesting_contract()); // Instantiate cw20 contract with balances for Alice @@ -343,7 +318,7 @@ pub fn test_instantiate_cw20_payroll_contract() { #[test] fn test_instantiate_wrong_ownership_native() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); + let code_id = app.store_code(cw_payroll_factory_contract()); let cw_vesting_code_id = app.store_code(cw_vesting_contract()); let amount = Uint128::new(1000000); @@ -413,7 +388,7 @@ fn test_instantiate_wrong_ownership_native() { #[test] fn test_update_vesting_code_id() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); + let code_id = app.store_code(cw_payroll_factory_contract()); let cw_vesting_code_id = app.store_code(cw_vesting_contract()); let cw_vesting_code_two = app.store_code(cw_vesting_contract()); @@ -512,8 +487,8 @@ fn test_update_vesting_code_id() { #[test] pub fn test_inconsistent_cw20_amount() { let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); + let code_id = app.store_code(cw_payroll_factory_contract()); + let cw20_code_id = app.store_code(cw20_base_contract()); let cw_vesting_code_id = app.store_code(cw_vesting_contract()); // Instantiate cw20 contract with balances for Alice let cw20_addr = app diff --git a/contracts/external/cw-token-swap/Cargo.toml b/contracts/external/cw-token-swap/Cargo.toml index e974d5453..4a44e1171 100644 --- a/contracts/external/cw-token-swap/Cargo.toml +++ b/contracts/external/cw-token-swap/Cargo.toml @@ -29,3 +29,4 @@ thiserror = { workspace = true } cosmwasm-schema = { workspace = true } cw-multi-test = { workspace = true } cw20-base = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/external/cw-token-swap/src/tests.rs b/contracts/external/cw-token-swap/src/tests.rs index e2d2a9913..b4c3b7be4 100644 --- a/contracts/external/cw-token-swap/src/tests.rs +++ b/contracts/external/cw-token-swap/src/tests.rs @@ -1,9 +1,10 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, Coin, Empty, Uint128, + to_json_binary, Addr, Coin, Uint128, }; use cw20::Cw20Coin; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{App, BankSudo, Executor, SudoMsg}; +use dao_testing::contracts::{cw20_base_contract, cw_token_swap_contract}; use crate::{ contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, @@ -17,30 +18,12 @@ use crate::{ const DAO1: &str = "dao1"; const DAO2: &str = "dao2"; -fn escrow_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - #[test] fn test_simple_escrow() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -140,8 +123,8 @@ fn test_simple_escrow() { fn test_withdraw() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -324,8 +307,8 @@ fn test_withdraw() { fn test_withdraw_post_completion() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -432,8 +415,8 @@ fn test_withdraw_post_completion() { fn test_invalid_instantiate() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -523,7 +506,7 @@ fn test_invalid_instantiate() { fn test_non_distincy_counterparties() { let mut app = App::default(); - let escrow_code = app.store_code(escrow_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); // Zero amount not allowed for native tokens. let err: ContractError = app @@ -561,8 +544,8 @@ fn test_non_distincy_counterparties() { fn test_fund_non_counterparty() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -658,8 +641,8 @@ fn test_fund_non_counterparty() { fn test_fund_twice() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -778,8 +761,8 @@ fn test_fund_twice() { fn test_fund_invalid_amount() { let mut app = App::default(); - let cw20_code = app.store_code(cw20_contract()); - let escrow_code = app.store_code(escrow_contract()); + let cw20_code = app.store_code(cw20_base_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let cw20 = app .instantiate_contract( @@ -883,7 +866,7 @@ fn test_fund_invalid_amount() { fn test_fund_invalid_denom() { let mut app = App::default(); - let escrow_code = app.store_code(escrow_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); let escrow = app .instantiate_contract( @@ -943,8 +926,8 @@ fn test_fund_invalid_denom() { fn test_fund_invalid_cw20() { let mut app = App::default(); - let escrow_code = app.store_code(escrow_contract()); - let cw20_code = app.store_code(cw20_contract()); + let escrow_code = app.store_code(cw_token_swap_contract()); + let cw20_code = app.store_code(cw20_base_contract()); let cw20 = app .instantiate_contract( diff --git a/contracts/external/cw-vesting/src/tests.rs b/contracts/external/cw-vesting/src/tests.rs index 9a55807b5..48e85f579 100644 --- a/contracts/external/cw-vesting/src/tests.rs +++ b/contracts/external/cw-vesting/src/tests.rs @@ -1,12 +1,10 @@ use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{coins, to_json_binary, Addr, Coin, Decimal, Empty, Uint128, Validator}; +use cosmwasm_std::{coins, to_json_binary, Addr, Coin, Decimal, Uint128, Validator}; use cw20::{Cw20Coin, Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw_denom::{CheckedDenom, UncheckedDenom}; -use cw_multi_test::{ - App, AppBuilder, BankSudo, Contract, ContractWrapper, Executor, StakingInfo, SudoMsg, -}; +use cw_multi_test::{App, AppBuilder, BankSudo, Executor, StakingInfo, SudoMsg}; use cw_ownable::Action; -use dao_testing::contracts::cw20_base_contract; +use dao_testing::contracts::{cw20_base_contract, cw_vesting_contract}; use crate::contract::{execute, execute_receive_cw20}; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg}; @@ -21,15 +19,6 @@ const TOTAL_VEST: u128 = 1000000; const OWNER: &str = "owner"; const NATIVE_DENOM: &str = "ujuno"; -fn cw_vesting_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - fn get_vesting_payment(app: &App, cw_vesting_addr: Addr) -> Vest { app.wrap() .query_wasm_smart(cw_vesting_addr, &QueryMsg::Info {}) diff --git a/contracts/external/cw721-roles/src/tests.rs b/contracts/external/cw721-roles/src/tests.rs index 41c559413..365772b9b 100644 --- a/contracts/external/cw721-roles/src/tests.rs +++ b/contracts/external/cw721-roles/src/tests.rs @@ -3,7 +3,7 @@ use cw4::{HooksResponse, Member, MemberListResponse, MemberResponse, TotalWeight use cw721::{NftInfoResponse, OwnerOfResponse}; use cw_multi_test::{App, Executor}; use dao_cw721_extensions::roles::{ExecuteExt, MetadataExt, QueryExt}; -use dao_testing::contracts::{cw721_roles_contract, cw721_staked_voting_contract}; +use dao_testing::contracts::{cw721_roles_contract, dao_voting_cw721_staked_contract}; use dao_voting_cw721_staked::msg::{InstantiateMsg as Cw721StakedInstantiateMsg, NftContract}; use crate::error::RolesContractError; @@ -254,7 +254,7 @@ fn test_send_permissions() { .unwrap(); // Instantiate an NFT staking voting contract for testing SendNft - let dao_voting_cw721_staked_id = app.store_code(cw721_staked_voting_contract()); + let dao_voting_cw721_staked_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_staked_addr = app .instantiate_contract( dao_voting_cw721_staked_id, diff --git a/contracts/external/dao-migrator/Cargo.toml b/contracts/external/dao-migrator/Cargo.toml index 4d2b48cb8..94018bf28 100644 --- a/contracts/external/dao-migrator/Cargo.toml +++ b/contracts/external/dao-migrator/Cargo.toml @@ -40,10 +40,10 @@ cw-core-v1 = { workspace = true, features = ["library"] } cw-proposal-single-v1 = { workspace = true, features = ["library"] } cw20-staked-balance-voting-v1 = { workspace = true, features = ["library"] } cw20-stake-v1 = { workspace = true, features = ["library"] } -cw-core-interface-v1 = { package = "cw-core-interface", version = "0.1.0", git = "https://github.com/DA0-DA0/dao-contracts.git", tag = "v1.0.0" } -cw4-voting-v1 = { package = "cw4-voting", version = "0.1.0", git = "https://github.com/DA0-DA0/dao-contracts.git", tag = "v1.0.0" } -cw20-v1 = { version = "0.13", package = "cw20" } -cw4-v1 = { version = "0.13", package = "cw4" } +cw-core-interface-v1 = { workspace = true } +cw4-voting-v1 = { workspace = true } +cw20-v1 = { workspace = true } +cw4-v1 = { workspace = true } [dev-dependencies] cosmwasm-schema = { workspace = true } diff --git a/contracts/external/dao-migrator/src/testing/helpers.rs b/contracts/external/dao-migrator/src/testing/helpers.rs index c25d13507..a65d5b753 100644 --- a/contracts/external/dao-migrator/src/testing/helpers.rs +++ b/contracts/external/dao-migrator/src/testing/helpers.rs @@ -5,8 +5,12 @@ use cosmwasm_std::{ use cw_multi_test::{next_block, App, Contract, ContractWrapper, Executor}; use dao_interface::query::SubDao; use dao_testing::contracts::{ - cw20_base_contract, cw20_staked_balances_voting_contract, cw4_group_contract, dao_dao_contract, - proposal_single_contract, v1_dao_dao_contract, v1_proposal_single_contract, + cw20_base_contract, cw20_stake_contract, cw4_group_contract, dao_dao_core_contract, + dao_proposal_single_contract, dao_voting_cw20_staked_contract, dao_voting_cw4_contract, + v1::{ + cw20_stake_v1_contract, cw4_voting_v1_contract, cw_core_v1_contract, + cw_proposal_single_v1_contract, + }, }; use crate::{ @@ -50,13 +54,13 @@ pub enum VotingType { pub fn get_v1_code_ids(app: &mut App) -> (CodeIds, V1CodeIds) { let code_ids = CodeIds { - core: app.store_code(v1_dao_dao_contract()), - proposal_single: app.store_code(v1_proposal_single_contract()), + core: app.store_code(cw_core_v1_contract()), + proposal_single: app.store_code(cw_proposal_single_v1_contract()), cw20_base: app.store_code(cw20_base_contract()), - cw20_stake: app.store_code(v1_cw20_stake_contract()), - cw20_voting: app.store_code(cw20_staked_balances_voting_contract()), + cw20_stake: app.store_code(cw20_stake_v1_contract()), + cw20_voting: app.store_code(dao_voting_cw20_staked_contract()), cw4_group: app.store_code(cw4_group_contract()), - cw4_voting: app.store_code(v1_cw4_voting_contract()), + cw4_voting: app.store_code(cw4_voting_v1_contract()), }; let v1_code_ids = V1CodeIds { @@ -70,10 +74,10 @@ pub fn get_v1_code_ids(app: &mut App) -> (CodeIds, V1CodeIds) { pub fn get_v2_code_ids(app: &mut App) -> (CodeIds, V2CodeIds) { let code_ids = CodeIds { - core: app.store_code(dao_dao_contract()), - proposal_single: app.store_code(proposal_single_contract()), + core: app.store_code(dao_dao_core_contract()), + proposal_single: app.store_code(dao_proposal_single_contract()), cw20_base: app.store_code(cw20_base_contract()), - cw20_stake: app.store_code(v2_cw20_stake_contract()), + cw20_stake: app.store_code(cw20_stake_contract()), cw20_voting: app.store_code(dao_voting_cw20_staked_contract()), cw4_group: app.store_code(cw4_group_contract()), cw4_voting: app.store_code(dao_voting_cw4_contract()), @@ -267,67 +271,6 @@ pub fn set_cw20_to_dao(app: &mut App, sender: Addr, addrs: ModuleAddrs) { ); } -pub fn dao_voting_cw20_staked_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_staked::contract::execute, - dao_voting_cw20_staked::contract::instantiate, - dao_voting_cw20_staked::contract::query, - ) - .with_reply(dao_voting_cw20_staked::contract::reply) - .with_migrate(dao_voting_cw20_staked::contract::migrate); - Box::new(contract) -} - -pub fn migrator_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -pub fn v1_cw20_stake_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake_v1::contract::execute, - cw20_stake_v1::contract::instantiate, - cw20_stake_v1::contract::query, - ); - Box::new(contract) -} - -pub fn v2_cw20_stake_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ) - .with_migrate(cw20_stake::contract::migrate); - Box::new(contract) -} - -pub fn v1_cw4_voting_contract() -> Box> { - let contract = ContractWrapper::new( - cw4_voting_v1::contract::execute, - cw4_voting_v1::contract::instantiate, - cw4_voting_v1::contract::query, - ) - .with_reply(cw4_voting_v1::contract::reply); - Box::new(contract) -} - -pub fn dao_voting_cw4_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw4::contract::execute, - dao_voting_cw4::contract::instantiate, - dao_voting_cw4::contract::query, - ) - .with_reply(dao_voting_cw4::contract::reply) - .with_migrate(dao_voting_cw4::contract::migrate); - Box::new(contract) -} - fn some_init( _deps: DepsMut, _env: Env, diff --git a/contracts/external/dao-migrator/src/testing/setup.rs b/contracts/external/dao-migrator/src/testing/setup.rs index becb49522..4b039a502 100644 --- a/contracts/external/dao-migrator/src/testing/setup.rs +++ b/contracts/external/dao-migrator/src/testing/setup.rs @@ -3,7 +3,7 @@ use std::borrow::BorrowMut; use cosmwasm_std::{to_json_binary, Addr, WasmMsg}; use cw_multi_test::{next_block, App, AppResponse, Executor}; use dao_interface::state::{Admin, ModuleInstantiateInfo}; -use dao_testing::contracts::stake_cw20_v03_contract; +use dao_testing::contracts::{dao_migrator_contract, v1::stake_cw20_v03_contract}; use crate::{ testing::helpers::get_module_addrs, @@ -11,8 +11,8 @@ use crate::{ }; use super::helpers::{ - get_cw20_init_msg, get_cw4_init_msg, get_v1_code_ids, get_v2_code_ids, migrator_contract, - set_cw20_to_dao, set_dummy_proposal, ExecuteParams, ModuleAddrs, VotingType, SENDER_ADDR, + get_cw20_init_msg, get_cw4_init_msg, get_v1_code_ids, get_v2_code_ids, set_cw20_to_dao, + set_dummy_proposal, ExecuteParams, ModuleAddrs, VotingType, SENDER_ADDR, }; pub fn init_v1(app: &mut App, sender: Addr, voting_type: VotingType) -> (Addr, V1CodeIds) { @@ -255,7 +255,7 @@ pub fn execute_migration( custom_proposal_params: Option>, ) -> Result { let sender = Addr::unchecked(SENDER_ADDR); - let migrator_code_id = app.store_code(migrator_contract()); + let migrator_code_id = app.store_code(dao_migrator_contract()); let (new_code_ids, v2_code_ids) = get_v2_code_ids(app); let params = params.unwrap_or_else(|| ExecuteParams { sub_daos: Some(vec![]), @@ -368,7 +368,7 @@ pub fn execute_migration_from_core( params: Option, ) -> Result { let sender = Addr::unchecked(SENDER_ADDR); - let migrator_code_id = app.store_code(migrator_contract()); + let migrator_code_id = app.store_code(dao_migrator_contract()); let (new_code_ids, v2_code_ids) = get_v2_code_ids(app); let params = params.unwrap_or_else(|| ExecuteParams { sub_daos: Some(vec![]), diff --git a/contracts/pre-propose/dao-pre-propose-approval-single/src/tests.rs b/contracts/pre-propose/dao-pre-propose-approval-single/src/tests.rs index 2e3f3e324..fe4cacd04 100644 --- a/contracts/pre-propose/dao-pre-propose-approval-single/src/tests.rs +++ b/contracts/pre-propose/dao-pre-propose-approval-single/src/tests.rs @@ -1,17 +1,25 @@ -use cosmwasm_std::{ - coins, from_json, to_json_binary, Addr, Coin, CosmosMsg, Empty, Uint128, WasmMsg, -}; +use cosmwasm_std::{coins, from_json, to_json_binary, Addr, Coin, CosmosMsg, Uint128, WasmMsg}; use cw2::ContractVersion; use cw20::Cw20Coin; use cw_denom::UncheckedDenom; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, BankSudo, Executor}; use cw_utils::Duration; use dao_interface::proposal::InfoResponse; use dao_interface::state::ProposalModule; use dao_interface::state::{Admin, ModuleInstantiateInfo}; use dao_pre_propose_base::{error::PreProposeError, msg::DepositInfoResponse, state::Config}; use dao_proposal_single::query::ProposalResponse; -use dao_testing::{contracts::cw4_group_contract, helpers::instantiate_with_cw4_groups_governance}; +use dao_testing::{ + contracts::{ + cw20_base_contract, cw4_group_contract, dao_pre_propose_approval_single_contract, + dao_proposal_single_contract, + v241::{ + dao_dao_core_v241_contract, dao_pre_propose_approval_single_v241_contract, + dao_proposal_single_v241_contract, dao_voting_cw4_v241_contract, + }, + }, + helpers::instantiate_with_cw4_groups_governance, +}; use dao_voting::pre_propose::{PreProposeSubmissionPolicy, PreProposeSubmissionPolicyError}; use dao_voting::{ deposit::{CheckedDepositInfo, DepositRefundPolicy, DepositToken, UncheckedDepositInfo}, @@ -22,7 +30,6 @@ use dao_voting::{ }; // test v2.4.1 migration -use dao_dao_core_v241 as core_v241; use dao_interface_v241 as di_v241; use dao_pre_propose_approval_single_v241 as dppas_v241; use dao_proposal_single_v241 as dps_v241; @@ -32,31 +39,6 @@ use dao_voting_v241 as dv_v241; use crate::state::{Proposal, ProposalStatus}; use crate::{contract::*, msg::*}; -fn dao_proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_single::contract::execute, - dao_proposal_single::contract::instantiate, - dao_proposal_single::contract::query, - ) - .with_migrate(dao_proposal_single::contract::migrate) - .with_reply(dao_proposal_single::contract::reply); - Box::new(contract) -} - -fn dao_pre_propose_approval_single_contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_migrate(migrate); - Box::new(contract) -} - -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn get_default_proposal_module_instantiate( app: &mut App, deposit_info: Option, @@ -2492,41 +2474,11 @@ fn test_withdraw() { fn test_migrate_from_v241() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dpps_v241_contract = Box::new(ContractWrapper::new( - dppas_v241::contract::execute, - dppas_v241::contract::instantiate, - dppas_v241::contract::query, - )); - let dps_v241_contract = Box::new( - ContractWrapper::new( - dps_v241::contract::execute, - dps_v241::contract::instantiate, - dps_v241::contract::query, - ) - .with_reply(dps_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dpps_v241_id = app.store_code(dpps_v241_contract); - let dps_v241_id = app.store_code(dps_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dpps_v241_id = app.store_code(dao_pre_propose_approval_single_v241_contract()); + let dps_v241_id = app.store_code(dao_proposal_single_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, @@ -2848,41 +2800,11 @@ fn test_migrate_from_v241() { fn test_migrate_from_v241_with_policy_update() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dpps_v241_contract = Box::new(ContractWrapper::new( - dppas_v241::contract::execute, - dppas_v241::contract::instantiate, - dppas_v241::contract::query, - )); - let dps_v241_contract = Box::new( - ContractWrapper::new( - dps_v241::contract::execute, - dps_v241::contract::instantiate, - dps_v241::contract::query, - ) - .with_reply(dps_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dpps_v241_id = app.store_code(dpps_v241_contract); - let dps_v241_id = app.store_code(dps_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dpps_v241_id = app.store_code(dao_pre_propose_approval_single_v241_contract()); + let dps_v241_id = app.store_code(dao_proposal_single_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, diff --git a/contracts/pre-propose/dao-pre-propose-approver/src/tests.rs b/contracts/pre-propose/dao-pre-propose-approver/src/tests.rs index c1475939a..8dc569995 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/src/tests.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/src/tests.rs @@ -1,8 +1,8 @@ -use cosmwasm_std::{coins, from_json, to_json_binary, Addr, Coin, Empty, Uint128}; +use cosmwasm_std::{coins, from_json, to_json_binary, Addr, Coin, Uint128}; use cw2::ContractVersion; use cw20::Cw20Coin; use cw_denom::UncheckedDenom; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, BankSudo, Executor}; use dao_interface::proposal::InfoResponse; use dao_voting::pre_propose::{PreProposeSubmissionPolicy, PreProposeSubmissionPolicyError}; use dps::query::{ProposalListResponse, ProposalResponse}; @@ -17,6 +17,10 @@ use dao_pre_propose_approval_single::{ }; use dao_pre_propose_base::{error::PreProposeError, msg::DepositInfoResponse, state::Config}; use dao_proposal_single as dps; +use dao_testing::contracts::{ + cw20_base_contract, dao_pre_propose_approval_single_contract, + dao_pre_propose_approver_contract, dao_proposal_single_contract, +}; use dao_testing::helpers::instantiate_with_cw4_groups_governance; use dao_voting::{ deposit::{CheckedDepositInfo, DepositRefundPolicy, DepositToken, UncheckedDepositInfo}, @@ -36,50 +40,12 @@ use crate::msg::{ // The approver dao contract is the 6th contract instantiated const APPROVER: &str = "contract6"; -fn cw_dao_proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - dps::contract::execute, - dps::contract::instantiate, - dps::contract::query, - ) - .with_migrate(dps::contract::migrate) - .with_reply(dps::contract::reply); - Box::new(contract) -} - -fn cw_pre_propose_base_proposal_single() -> Box> { - let contract = ContractWrapper::new( - dao_pre_propose_approval_single::contract::execute, - dao_pre_propose_approval_single::contract::instantiate, - dao_pre_propose_approval_single::contract::query, - ); - Box::new(contract) -} - -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn pre_propose_approver_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - fn get_proposal_module_approval_single_instantiate( app: &mut App, deposit_info: Option, open_proposal_submission: bool, ) -> dps::msg::InstantiateMsg { - let pre_propose_id = app.store_code(cw_pre_propose_base_proposal_single()); + let pre_propose_id = app.store_code(dao_pre_propose_approval_single_contract()); let submission_policy = if open_proposal_submission { PreProposeSubmissionPolicy::Anyone { denylist: vec![] } @@ -126,7 +92,7 @@ fn get_proposal_module_approver_instantiate( _open_proposal_submission: bool, pre_propose_approval_contract: String, ) -> dps::msg::InstantiateMsg { - let pre_propose_id = app.store_code(pre_propose_approver_contract()); + let pre_propose_id = app.store_code(dao_pre_propose_approver_contract()); dps::msg::InstantiateMsg { threshold: Threshold::AbsolutePercentage { @@ -191,7 +157,7 @@ fn setup_default_test( deposit_info: Option, open_proposal_submission: bool, ) -> DefaultTestSetup { - let dps_id = app.store_code(cw_dao_proposal_single_contract()); + let dps_id = app.store_code(dao_proposal_single_contract()); // Instantiate SubDAO with pre-propose-approval-single let proposal_module_instantiate = get_proposal_module_approval_single_instantiate( diff --git a/contracts/pre-propose/dao-pre-propose-multiple/src/tests.rs b/contracts/pre-propose/dao-pre-propose-multiple/src/tests.rs index f949702c2..e27c14e17 100644 --- a/contracts/pre-propose/dao-pre-propose-multiple/src/tests.rs +++ b/contracts/pre-propose/dao-pre-propose-multiple/src/tests.rs @@ -5,14 +5,24 @@ use cpm::query::ProposalResponse; use cw2::ContractVersion; use cw20::Cw20Coin; use cw_denom::UncheckedDenom; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, BankSudo, Executor}; use cw_utils::Duration; use dao_interface::proposal::InfoResponse; use dao_interface::state::ProposalModule; use dao_interface::state::{Admin, ModuleInstantiateInfo}; use dao_pre_propose_base::{error::PreProposeError, msg::DepositInfoResponse, state::Config}; use dao_proposal_multiple as cpm; -use dao_testing::{contracts::cw4_group_contract, helpers::instantiate_with_cw4_groups_governance}; +use dao_testing::{ + contracts::{ + cw20_base_contract, cw4_group_contract, dao_pre_propose_multiple_contract, + dao_proposal_multiple_contract, + v241::{ + dao_dao_core_v241_contract, dao_pre_propose_multiple_v241_contract, + dao_proposal_multiple_v241_contract, dao_voting_cw4_v241_contract, + }, + }, + helpers::instantiate_with_cw4_groups_governance, +}; use dao_voting::multiple_choice::MultipleChoiceAutoVote; use dao_voting::pre_propose::{PreProposeSubmissionPolicy, PreProposeSubmissionPolicyError}; use dao_voting::{ @@ -27,7 +37,6 @@ use dao_voting::{ }; // test v2.4.1 migration -use dao_dao_core_v241 as core_v241; use dao_interface_v241 as di_v241; use dao_pre_propose_multiple_v241 as dppm_v241; use dao_proposal_multiple_v241 as dpm_v241; @@ -36,30 +45,6 @@ use dao_voting_v241 as dv_v241; use crate::contract::*; -fn dao_proposal_multiple_contract() -> Box> { - let contract = ContractWrapper::new( - cpm::contract::execute, - cpm::contract::instantiate, - cpm::contract::query, - ) - .with_reply(cpm::contract::reply); - Box::new(contract) -} - -fn dao_pre_propose_multiple_contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_migrate(migrate); - Box::new(contract) -} - -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn get_default_proposal_module_instantiate( app: &mut App, deposit_info: Option, @@ -2247,41 +2232,11 @@ fn test_withdraw() { fn test_migrate_from_v241() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dppm_v241_contract = Box::new(ContractWrapper::new( - dppm_v241::contract::execute, - dppm_v241::contract::instantiate, - dppm_v241::contract::query, - )); - let dpm_v241_contract = Box::new( - ContractWrapper::new( - dpm_v241::contract::execute, - dpm_v241::contract::instantiate, - dpm_v241::contract::query, - ) - .with_reply(dpm_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dppm_v241_id = app.store_code(dppm_v241_contract); - let dpm_v241_id = app.store_code(dpm_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dppm_v241_id = app.store_code(dao_pre_propose_multiple_v241_contract()); + let dpm_v241_id = app.store_code(dao_proposal_multiple_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, @@ -2629,41 +2584,11 @@ fn test_migrate_from_v241() { fn test_migrate_from_v241_with_policy_update() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dppm_v241_contract = Box::new(ContractWrapper::new( - dppm_v241::contract::execute, - dppm_v241::contract::instantiate, - dppm_v241::contract::query, - )); - let dpm_v241_contract = Box::new( - ContractWrapper::new( - dpm_v241::contract::execute, - dpm_v241::contract::instantiate, - dpm_v241::contract::query, - ) - .with_reply(dpm_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dppm_v241_id = app.store_code(dppm_v241_contract); - let dpm_v241_id = app.store_code(dpm_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dppm_v241_id = app.store_code(dao_pre_propose_multiple_v241_contract()); + let dpm_v241_id = app.store_code(dao_proposal_multiple_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, diff --git a/contracts/pre-propose/dao-pre-propose-single/src/tests.rs b/contracts/pre-propose/dao-pre-propose-single/src/tests.rs index a8eef5e3e..8c037240c 100644 --- a/contracts/pre-propose/dao-pre-propose-single/src/tests.rs +++ b/contracts/pre-propose/dao-pre-propose-single/src/tests.rs @@ -4,14 +4,24 @@ use cosmwasm_std::{ use cw2::ContractVersion; use cw20::Cw20Coin; use cw_denom::UncheckedDenom; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, BankSudo, Executor}; use cw_utils::Duration; use dao_interface::proposal::InfoResponse; use dao_interface::state::ProposalModule; use dao_interface::state::{Admin, ModuleInstantiateInfo}; use dao_pre_propose_base::{error::PreProposeError, msg::DepositInfoResponse, state::Config}; use dao_proposal_single as dps; -use dao_testing::{contracts::cw4_group_contract, helpers::instantiate_with_cw4_groups_governance}; +use dao_testing::{ + contracts::{ + cw20_base_contract, cw4_group_contract, dao_pre_propose_single_contract, + dao_proposal_single_contract, + v241::{ + dao_dao_core_v241_contract, dao_pre_propose_single_v241_contract, + dao_proposal_single_v241_contract, dao_voting_cw4_v241_contract, + }, + }, + helpers::instantiate_with_cw4_groups_governance, +}; use dao_voting::pre_propose::{PreProposeSubmissionPolicy, PreProposeSubmissionPolicyError}; use dao_voting::{ deposit::{CheckedDepositInfo, DepositRefundPolicy, DepositToken, UncheckedDepositInfo}, @@ -23,7 +33,6 @@ use dao_voting::{ use dps::query::ProposalResponse; // test v2.4.1 migration -use dao_dao_core_v241 as core_v241; use dao_interface_v241 as di_v241; use dao_pre_propose_single_v241 as dpps_v241; use dao_proposal_single_v241 as dps_v241; @@ -32,31 +41,6 @@ use dao_voting_v241 as dv_v241; use crate::contract::*; -fn dao_proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - dps::contract::execute, - dps::contract::instantiate, - dps::contract::query, - ) - .with_migrate(dps::contract::migrate) - .with_reply(dps::contract::reply); - Box::new(contract) -} - -fn dao_pre_propose_single_contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_migrate(migrate); - Box::new(contract) -} - -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn get_default_proposal_module_instantiate( app: &mut App, deposit_info: Option, @@ -2186,41 +2170,11 @@ fn test_hook_management() { fn test_migrate_from_v241() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dpps_v241_contract = Box::new(ContractWrapper::new( - dpps_v241::contract::execute, - dpps_v241::contract::instantiate, - dpps_v241::contract::query, - )); - let dps_v241_contract = Box::new( - ContractWrapper::new( - dps_v241::contract::execute, - dps_v241::contract::instantiate, - dps_v241::contract::query, - ) - .with_reply(dps_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dpps_v241_id = app.store_code(dpps_v241_contract); - let dps_v241_id = app.store_code(dps_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dpps_v241_id = app.store_code(dao_pre_propose_single_v241_contract()); + let dps_v241_id = app.store_code(dao_proposal_single_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, @@ -2513,41 +2467,11 @@ fn test_migrate_from_v241() { fn test_migrate_from_v241_with_policy_update() { let app = &mut App::default(); - let core_v241_contract = Box::new( - ContractWrapper::new( - core_v241::contract::execute, - core_v241::contract::instantiate, - core_v241::contract::query, - ) - .with_reply(core_v241::contract::reply), - ); - let dvcw4_v241_contract = Box::new( - ContractWrapper::new( - dvcw4_v241::contract::execute, - dvcw4_v241::contract::instantiate, - dvcw4_v241::contract::query, - ) - .with_reply(dvcw4_v241::contract::reply), - ); - let dpps_v241_contract = Box::new(ContractWrapper::new( - dpps_v241::contract::execute, - dpps_v241::contract::instantiate, - dpps_v241::contract::query, - )); - let dps_v241_contract = Box::new( - ContractWrapper::new( - dps_v241::contract::execute, - dps_v241::contract::instantiate, - dps_v241::contract::query, - ) - .with_reply(dps_v241::contract::reply), - ); - - let core_id = app.store_code(core_v241_contract); + let core_id = app.store_code(dao_dao_core_v241_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let dvcw4_v241_id = app.store_code(dvcw4_v241_contract); - let dpps_v241_id = app.store_code(dpps_v241_contract); - let dps_v241_id = app.store_code(dps_v241_contract); + let dvcw4_v241_id = app.store_code(dao_voting_cw4_v241_contract()); + let dpps_v241_id = app.store_code(dao_pre_propose_single_v241_contract()); + let dps_v241_id = app.store_code(dao_proposal_single_v241_contract()); let governance_instantiate = di_v241::msg::InstantiateMsg { dao_uri: None, diff --git a/contracts/proposal/dao-proposal-condorcet/src/testing/suite.rs b/contracts/proposal/dao-proposal-condorcet/src/testing/suite.rs index c268bc5c1..7ab46d511 100644 --- a/contracts/proposal/dao-proposal-condorcet/src/testing/suite.rs +++ b/contracts/proposal/dao-proposal-condorcet/src/testing/suite.rs @@ -6,7 +6,8 @@ use dao_interface::{ voting::InfoResponse, }; use dao_testing::contracts::{ - cw4_group_contract, dao_dao_contract, dao_voting_cw4_contract, proposal_condorcet_contract, + cw4_group_contract, dao_dao_core_contract, dao_proposal_condorcet_contract, + dao_voting_cw4_contract, }; use dao_voting::threshold::PercentageThreshold; use dao_voting_cw4::msg::GroupContract; @@ -74,8 +75,8 @@ impl SuiteBuilder { let sender = Addr::unchecked(&initial_members[0].addr); let mut app = App::default(); - let condorcet_id = app.store_code(proposal_condorcet_contract()); - let core_id = app.store_code(dao_dao_contract()); + let condorcet_id = app.store_code(dao_proposal_condorcet_contract()); + let core_id = app.store_code(dao_dao_core_contract()); let cw4_id = app.store_code(cw4_group_contract()); let cw4_voting_id = app.store_code(dao_voting_cw4_contract()); diff --git a/contracts/proposal/dao-proposal-multiple/src/testing/do_votes.rs b/contracts/proposal/dao-proposal-multiple/src/testing/do_votes.rs index 51a0747b8..959c96da3 100644 --- a/contracts/proposal/dao-proposal-multiple/src/testing/do_votes.rs +++ b/contracts/proposal/dao-proposal-multiple/src/testing/do_votes.rs @@ -3,7 +3,7 @@ use cw20::Cw20Coin; use cw_denom::CheckedDenom; use cw_multi_test::{App, BankSudo, Executor}; use dao_interface::state::ProposalModule; -use dao_testing::ShouldExecute; +use dao_testing::{contracts::dao_proposal_multiple_contract, ShouldExecute}; use dao_voting::{ deposit::{CheckedDepositInfo, UncheckedDepositInfo}, multiple_choice::{ @@ -23,7 +23,7 @@ use crate::{ instantiate_with_cw20_balances_governance, instantiate_with_staked_balances_governance, }, queries::query_deposit_config_and_pre_propose_module, - tests::{get_pre_propose_info, proposal_multiple_contract, TestMultipleChoiceVote}, + tests::{get_pre_propose_info, TestMultipleChoiceVote}, }, }; use dao_pre_propose_multiple as cppm; @@ -96,7 +96,7 @@ where F: Fn(&mut App, InstantiateMsg, Option>) -> Addr, { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let mut initial_balances = votes .iter() diff --git a/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs b/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs index 693edfbb0..bb0eacb29 100644 --- a/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs +++ b/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs @@ -1,13 +1,14 @@ use cosmwasm_std::{to_json_binary, Addr, Coin, Empty, Uint128}; use cw20::Cw20Coin; -use cw_multi_test::{next_block, App, BankSudo, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; use cw_utils::Duration; use dao_interface::state::{Admin, ModuleInstantiateInfo}; use dao_pre_propose_multiple as cppm; use dao_testing::contracts::{ - cw20_balances_voting_contract, cw20_base_contract, cw20_stake_contract, - cw20_staked_balances_voting_contract, cw4_group_contract, cw721_base_contract, - dao_dao_contract, native_staked_balances_voting_contract, pre_propose_multiple_contract, + cw20_base_contract, cw20_stake_contract, cw4_group_contract, cw721_base_contract, + dao_dao_core_contract, dao_pre_propose_multiple_contract, dao_proposal_multiple_contract, + dao_voting_cw20_balance_contract, dao_voting_cw20_staked_contract, + dao_voting_cw721_staked_contract, dao_voting_token_staked_contract, }; use dao_voting::{ deposit::{DepositRefundPolicy, UncheckedDepositInfo, VotingModuleTokenType}, @@ -21,9 +22,7 @@ use dao_voting::{ use dao_voting_cw4::msg::GroupContract; use crate::testing::tests::ALTERNATIVE_ADDR; -use crate::{ - msg::InstantiateMsg, testing::tests::proposal_multiple_contract, testing::tests::CREATOR_ADDR, -}; +use crate::{msg::InstantiateMsg, testing::tests::CREATOR_ADDR}; #[allow(dead_code)] fn get_pre_propose_info( @@ -31,7 +30,7 @@ fn get_pre_propose_info( deposit_info: Option, open_proposal_submission: bool, ) -> PreProposeInfo { - let pre_propose_contract = app.store_code(pre_propose_multiple_contract()); + let pre_propose_contract = app.store_code(dao_pre_propose_multiple_contract()); let submission_policy = if open_proposal_submission { PreProposeSubmissionPolicy::Anyone { denylist: vec![] } @@ -107,7 +106,7 @@ pub fn _instantiate_with_staked_cw721_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -132,15 +131,8 @@ pub fn _instantiate_with_staked_cw721_governance( }; let cw721_id = app.store_code(cw721_base_contract()); - let cw721_stake_id = app.store_code({ - let contract = ContractWrapper::new( - dao_voting_cw721_staked::contract::execute, - dao_voting_cw721_staked::contract::instantiate, - dao_voting_cw721_staked::contract::query, - ); - Box::new(contract) - }); - let core_contract_id = app.store_code(dao_dao_contract()); + let cw721_stake_id = app.store_code(dao_voting_cw721_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let nft_address = app .instantiate_contract( @@ -248,7 +240,7 @@ pub fn instantiate_with_native_staked_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -273,8 +265,8 @@ pub fn instantiate_with_native_staked_balances_governance( .collect() }; - let native_stake_id = app.store_code(native_staked_balances_voting_contract()); - let core_contract_id = app.store_code(dao_dao_contract()); + let native_stake_id = app.store_code(dao_voting_token_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { admin: None, @@ -360,11 +352,11 @@ pub fn instantiate_with_cw20_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let cw20_id = app.store_code(cw20_base_contract()); - let core_id = app.store_code(dao_dao_contract()); - let votemod_id = app.store_code(cw20_balances_voting_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_balance_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -441,7 +433,7 @@ pub fn instantiate_with_staked_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -468,8 +460,8 @@ pub fn instantiate_with_staked_balances_governance( let cw20_id = app.store_code(cw20_base_contract()); let cw20_stake_id = app.store_code(cw20_stake_contract()); - let staked_balances_voting_id = app.store_code(cw20_staked_balances_voting_contract()); - let core_contract_id = app.store_code(dao_dao_contract()); + let staked_balances_voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { admin: None, @@ -572,7 +564,7 @@ pub fn instantiate_with_multiple_staked_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![ @@ -605,8 +597,8 @@ pub fn instantiate_with_multiple_staked_balances_governance( let cw20_id = app.store_code(cw20_base_contract()); let cw20_stake_id = app.store_code(cw20_stake_contract()); - let staked_balances_voting_id = app.store_code(cw20_staked_balances_voting_contract()); - let core_contract_id = app.store_code(dao_dao_contract()); + let staked_balances_voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { admin: None, @@ -712,11 +704,11 @@ pub fn instantiate_with_staking_active_threshold( initial_balances: Option>, active_threshold: Option, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let cw20_id = app.store_code(cw20_base_contract()); let cw20_staking_id = app.store_code(cw20_stake_contract()); - let core_id = app.store_code(dao_dao_contract()); - let votemod_id = app.store_code(cw20_staked_balances_voting_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_staked_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -781,9 +773,9 @@ pub fn _instantiate_with_cw4_groups_governance( proposal_module_instantiate: InstantiateMsg, initial_weights: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_multiple_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_multiple_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let core_id = app.store_code(dao_dao_contract()); + let core_id = app.store_code(dao_dao_core_contract()); let votemod_id = app.store_code(cw4_group_contract()); let initial_weights = initial_weights.unwrap_or_else(|| { diff --git a/contracts/proposal/dao-proposal-multiple/src/testing/tests.rs b/contracts/proposal/dao-proposal-multiple/src/testing/tests.rs index 2b82b7ce7..c3a472331 100644 --- a/contracts/proposal/dao-proposal-multiple/src/testing/tests.rs +++ b/contracts/proposal/dao-proposal-multiple/src/testing/tests.rs @@ -4,7 +4,7 @@ use cosmwasm_std::{ use cw20::Cw20Coin; use cw_denom::{CheckedDenom, UncheckedDenom}; use cw_hooks::HooksResponse; -use cw_multi_test::{next_block, App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; +use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; use cw_utils::Duration; use dao_interface::state::ProposalModule; use dao_interface::state::{Admin, ModuleInstantiateInfo}; @@ -54,7 +54,10 @@ use crate::{ use dao_pre_propose_multiple as cppm; use dao_testing::{ - contracts::{cw20_balances_voting_contract, cw20_base_contract}, + contracts::{ + cw20_base_contract, dao_pre_propose_multiple_contract, dao_proposal_multiple_contract, + dao_voting_cw20_balance_contract, + }, ShouldExecute, }; @@ -72,31 +75,12 @@ pub struct TestMultipleChoiceVote { pub should_execute: ShouldExecute, } -pub fn proposal_multiple_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -pub fn pre_propose_multiple_contract() -> Box> { - let contract = ContractWrapper::new( - cppm::contract::execute, - cppm::contract::instantiate, - cppm::contract::query, - ); - Box::new(contract) -} - pub fn get_pre_propose_info( app: &mut App, deposit_info: Option, open_proposal_submission: bool, ) -> PreProposeInfo { - let pre_propose_contract = app.store_code(pre_propose_multiple_contract()); + let pre_propose_contract = app.store_code(dao_pre_propose_multiple_contract()); let submission_policy = if open_proposal_submission { PreProposeSubmissionPolicy::Anyone { denylist: vec![] } @@ -127,7 +111,7 @@ pub fn get_pre_propose_info( #[test] fn test_propose() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -209,7 +193,7 @@ fn test_propose() { #[test] fn test_propose_wrong_num_choices() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = cw_utils::Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -293,7 +277,7 @@ fn test_propose_wrong_num_choices() { #[test] fn test_proposal_count_initialized_to_zero() { let mut app = App::default(); - let _proposal_id = app.store_code(proposal_multiple_contract()); + let _proposal_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -328,7 +312,7 @@ fn test_proposal_count_initialized_to_zero() { #[test] fn test_propose_auto_vote_winner() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -419,7 +403,7 @@ fn test_propose_auto_vote_winner() { #[test] fn test_propose_auto_vote_reject() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -511,7 +495,7 @@ fn test_propose_auto_vote_reject() { #[should_panic(expected = "Not registered to vote (no voting power) at time of proposal creation")] fn test_propose_non_member_auto_vote_fail() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -577,7 +561,7 @@ fn test_propose_non_member_auto_vote_fail() { #[test] fn test_no_early_pass_with_min_duration() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -673,7 +657,7 @@ fn test_no_early_pass_with_min_duration() { #[test] fn test_propose_with_messages() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -795,7 +779,7 @@ fn test_propose_with_messages() { )] fn test_min_duration_units_missmatch() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -828,7 +812,7 @@ fn test_min_duration_units_missmatch() { #[should_panic(expected = "Min voting period must be less than or equal to max voting period")] fn test_min_duration_larger_than_proposal_duration() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -860,7 +844,7 @@ fn test_min_duration_larger_than_proposal_duration() { #[test] fn test_min_duration_same_as_proposal_duration() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let msg = InstantiateMsg { voting_strategy: VotingStrategy::SingleChoice { quorum: PercentageThreshold::Percent(Decimal::percent(10)), @@ -971,7 +955,7 @@ fn test_min_duration_same_as_proposal_duration() { #[test] fn test_voting_module_token_proposal_deposit_instantiate() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -1030,7 +1014,7 @@ fn test_voting_module_token_proposal_deposit_instantiate() { #[test] fn test_different_token_proposal_deposit() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let cw20_id = app.store_code(cw20_base_contract()); let cw20_addr = app .instantiate_contract( @@ -1084,9 +1068,9 @@ fn test_different_token_proposal_deposit() { #[should_panic(expected = "Error parsing into type dao_voting_cw20_balance::msg::QueryMsg")] fn test_bad_token_proposal_deposit() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let cw20_id = app.store_code(cw20_base_contract()); - let votemod_id = app.store_code(cw20_balances_voting_contract()); + let votemod_id = app.store_code(dao_voting_cw20_balance_contract()); let votemod_addr = app .instantiate_contract( @@ -1142,7 +1126,7 @@ fn test_bad_token_proposal_deposit() { #[test] fn test_take_proposal_deposit() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Percent(Decimal::percent(10)); let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -1250,7 +1234,7 @@ fn test_take_proposal_deposit() { #[test] fn test_take_native_proposal_deposit() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Percent(Decimal::percent(10)); let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -1345,7 +1329,7 @@ fn test_take_native_proposal_deposit() { #[test] fn test_native_proposal_deposit() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = cw_utils::Duration::Height(6); let instantiate = InstantiateMsg { @@ -1777,7 +1761,7 @@ fn test_cant_vote_executed_or_closed() { #[test] fn test_cant_propose_zero_power() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Percent(Decimal::percent(10)); let voting_strategy = VotingStrategy::SingleChoice { quorum }; let max_voting_period = cw_utils::Duration::Height(6); @@ -1953,7 +1937,7 @@ fn test_cant_vote_not_registered() { fn test_cant_execute_not_member() { // Create proposal with only_members_execute: true let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = cw_utils::Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -2045,7 +2029,7 @@ fn test_cant_execute_not_member_when_proposal_created() { // Create proposal with only_members_execute: true and ensure member cannot // execute if they were not a member when the proposal was created let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = cw_utils::Duration::Height(6); let quorum = PercentageThreshold::Majority {}; @@ -2164,7 +2148,7 @@ fn test_cant_execute_not_member_when_proposal_created() { #[test] fn test_open_proposal_submission() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let max_voting_period = cw_utils::Duration::Height(6); @@ -2469,7 +2453,7 @@ fn test_deposit_return_on_close() { #[test] fn test_execute_expired_proposal() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Percent(Decimal::percent(10)); let voting_strategy = VotingStrategy::SingleChoice { quorum }; let max_voting_period = cw_utils::Duration::Height(6); @@ -2768,7 +2752,7 @@ fn test_no_return_if_no_refunds() { #[test] fn test_query_list_proposals() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; let max_voting_period = cw_utils::Duration::Height(6); @@ -2904,7 +2888,7 @@ fn test_query_list_proposals() { #[test] fn test_hooks() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -3031,7 +3015,7 @@ fn test_hooks() { #[test] fn test_active_threshold_absolute() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -3163,7 +3147,7 @@ fn test_active_threshold_absolute() { #[test] fn test_active_threshold_percent() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; let max_voting_period = cw_utils::Duration::Height(6); @@ -3295,7 +3279,7 @@ fn test_active_threshold_percent() { #[test] fn test_active_threshold_none() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; let max_voting_period = cw_utils::Duration::Height(6); @@ -3407,7 +3391,7 @@ fn test_active_threshold_none() { #[test] fn test_revoting() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let core_addr = instantiate_with_staked_balances_governance( &mut app, InstantiateMsg { @@ -3541,7 +3525,7 @@ fn test_revoting() { #[test] fn test_allow_revoting_config_changes() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let core_addr = instantiate_with_staked_balances_governance( &mut app, InstantiateMsg { @@ -3696,7 +3680,7 @@ fn test_allow_revoting_config_changes() { #[test] fn test_revoting_same_vote_twice() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let core_addr = instantiate_with_staked_balances_governance( &mut app, InstantiateMsg { @@ -3792,7 +3776,7 @@ fn test_revoting_same_vote_twice() { #[test] fn test_invalid_revote_does_not_invalidate_initial_vote() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let core_addr = instantiate_with_staked_balances_governance( &mut app, InstantiateMsg { @@ -3987,7 +3971,7 @@ fn test_return_deposit_to_dao_on_proposal_failure() { #[test] fn test_close_failed_proposal() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let quorum = PercentageThreshold::Majority {}; let voting_strategy = VotingStrategy::SingleChoice { quorum }; @@ -4228,7 +4212,7 @@ fn test_close_failed_proposal() { #[test] fn test_no_double_refund_on_execute_fail_and_close() { let mut app = App::default(); - let _proposal_module_id = app.store_code(proposal_multiple_contract()); + let _proposal_module_id = app.store_code(dao_proposal_multiple_contract()); let voting_strategy = VotingStrategy::SingleChoice { quorum: PercentageThreshold::Majority {}, @@ -4424,7 +4408,7 @@ fn test_no_double_refund_on_execute_fail_and_close() { #[test] pub fn test_not_allow_voting_on_expired_proposal() { let mut app = App::default(); - let _govmod_id = app.store_code(proposal_multiple_contract()); + let _govmod_id = app.store_code(dao_proposal_multiple_contract()); let instantiate = InstantiateMsg { max_voting_period: Duration::Height(6), only_members_execute: false, diff --git a/contracts/proposal/dao-proposal-single/src/testing/contracts.rs b/contracts/proposal/dao-proposal-single/src/testing/contracts.rs deleted file mode 100644 index d222acbc5..000000000 --- a/contracts/proposal/dao-proposal-single/src/testing/contracts.rs +++ /dev/null @@ -1,108 +0,0 @@ -use cosmwasm_std::Empty; - -use cw_multi_test::{Contract, ContractWrapper}; -use dao_pre_propose_single as cppbps; - -pub(crate) fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn cw4_group_contract() -> Box> { - let contract = ContractWrapper::new( - cw4_group::contract::execute, - cw4_group::contract::instantiate, - cw4_group::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn cw721_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw721_base::entry::execute, - cw721_base::entry::instantiate, - cw721_base::entry::query, - ); - Box::new(contract) -} - -pub(crate) fn cw20_stake_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -pub(crate) fn pre_propose_single_contract() -> Box> { - let contract = ContractWrapper::new( - cppbps::contract::execute, - cppbps::contract::instantiate, - cppbps::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn cw20_staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_staked::contract::execute, - dao_voting_cw20_staked::contract::instantiate, - dao_voting_cw20_staked::contract::query, - ) - .with_reply(dao_voting_cw20_staked::contract::reply); - Box::new(contract) -} - -pub(crate) fn native_staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_token_staked::contract::execute, - dao_voting_token_staked::contract::instantiate, - dao_voting_token_staked::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn cw721_stake_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw721_staked::contract::execute, - dao_voting_cw721_staked::contract::instantiate, - dao_voting_cw721_staked::contract::query, - ); - Box::new(contract) -} - -pub(crate) fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply); - Box::new(contract) -} - -pub(crate) fn cw4_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw4::contract::execute, - dao_voting_cw4::contract::instantiate, - dao_voting_cw4::contract::query, - ) - .with_reply(dao_voting_cw4::contract::reply); - Box::new(contract) -} diff --git a/contracts/proposal/dao-proposal-single/src/testing/execute.rs b/contracts/proposal/dao-proposal-single/src/testing/execute.rs index c8511271f..8b41b5c8f 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/execute.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/execute.rs @@ -3,6 +3,7 @@ use cw_multi_test::{App, BankSudo, Executor}; use cw_denom::CheckedDenom; use dao_pre_propose_single as cppbps; +use dao_testing::contracts::cw20_base_contract; use dao_voting::{ deposit::CheckedDepositInfo, pre_propose::ProposalCreationPolicy, @@ -17,9 +18,7 @@ use crate::{ ContractError, }; -use super::{ - contracts::cw20_base_contract, queries::query_pre_proposal_single_config, CREATOR_ADDR, -}; +use super::{queries::query_pre_proposal_single_config, CREATOR_ADDR}; // Creates a proposal then checks that the proposal was created with // the specified messages and returns the ID of the proposal. diff --git a/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs b/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs index 217ad740f..4f469476f 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs @@ -6,6 +6,12 @@ use cw_utils::Duration; use dao_interface::state::{Admin, ModuleInstantiateInfo}; use dao_pre_propose_single as cppbps; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, cw4_group_contract, cw721_base_contract, + dao_dao_core_contract, dao_pre_propose_single_contract, dao_proposal_single_contract, + dao_voting_cw20_staked_contract, dao_voting_cw4_contract, dao_voting_cw721_staked_contract, + dao_voting_token_staked_contract, +}; use dao_voting::{ deposit::{DepositRefundPolicy, UncheckedDepositInfo, VotingModuleTokenType}, pre_propose::{PreProposeInfo, PreProposeSubmissionPolicy}, @@ -15,22 +21,14 @@ use dao_voting_cw4::msg::GroupContract; use crate::msg::InstantiateMsg; -use super::{ - contracts::{ - cw20_base_contract, cw20_stake_contract, cw20_staked_balances_voting_contract, - cw4_group_contract, cw4_voting_contract, cw721_base_contract, cw721_stake_contract, - cw_core_contract, native_staked_balances_voting_contract, proposal_single_contract, - }, - CREATOR_ADDR, -}; +use super::CREATOR_ADDR; pub(crate) fn get_pre_propose_info( app: &mut App, deposit_info: Option, open_proposal_submission: bool, ) -> PreProposeInfo { - let pre_propose_contract = - app.store_code(crate::testing::contracts::pre_propose_single_contract()); + let pre_propose_contract = app.store_code(dao_pre_propose_single_contract()); let submission_policy = if open_proposal_submission { PreProposeSubmissionPolicy::Anyone { denylist: vec![] } @@ -108,7 +106,7 @@ pub(crate) fn instantiate_with_staked_cw721_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_single_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_single_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -133,8 +131,8 @@ pub(crate) fn instantiate_with_staked_cw721_governance( }; let cw721_id = app.store_code(cw721_base_contract()); - let cw721_stake_id = app.store_code(cw721_stake_contract()); - let core_contract_id = app.store_code(cw_core_contract()); + let cw721_stake_id = app.store_code(dao_voting_cw721_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let nft_address = app .instantiate_contract( @@ -242,7 +240,7 @@ pub(crate) fn instantiate_with_native_staked_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_single_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_single_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -267,8 +265,8 @@ pub(crate) fn instantiate_with_native_staked_balances_governance( .collect() }; - let native_stake_id = app.store_code(native_staked_balances_voting_contract()); - let core_contract_id = app.store_code(cw_core_contract()); + let native_stake_id = app.store_code(dao_voting_token_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { admin: None, @@ -353,7 +351,7 @@ pub(crate) fn instantiate_with_staked_balances_governance( proposal_module_instantiate: InstantiateMsg, initial_balances: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_single_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_single_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -380,8 +378,8 @@ pub(crate) fn instantiate_with_staked_balances_governance( let cw20_id = app.store_code(cw20_base_contract()); let cw20_stake_id = app.store_code(cw20_stake_contract()); - let staked_balances_voting_id = app.store_code(cw20_staked_balances_voting_contract()); - let core_contract_id = app.store_code(cw_core_contract()); + let staked_balances_voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { admin: None, @@ -485,11 +483,11 @@ pub(crate) fn instantiate_with_staking_active_threshold( initial_balances: Option>, active_threshold: Option, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_single_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_single_contract()); let cw20_id = app.store_code(cw20_base_contract()); let cw20_staking_id = app.store_code(cw20_stake_contract()); - let core_id = app.store_code(cw_core_contract()); - let votemod_id = app.store_code(cw20_staked_balances_voting_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_staked_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -554,10 +552,10 @@ pub(crate) fn instantiate_with_cw4_groups_governance( proposal_module_instantiate: InstantiateMsg, initial_weights: Option>, ) -> Addr { - let proposal_module_code_id = app.store_code(proposal_single_contract()); + let proposal_module_code_id = app.store_code(dao_proposal_single_contract()); let cw4_id = app.store_code(cw4_group_contract()); - let core_id = app.store_code(cw_core_contract()); - let votemod_id = app.store_code(cw4_voting_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw4_contract()); let initial_weights = initial_weights.unwrap_or_else(|| { vec![Cw20Coin { diff --git a/contracts/proposal/dao-proposal-single/src/testing/migration_tests.rs b/contracts/proposal/dao-proposal-single/src/testing/migration_tests.rs index 83196d8cf..2aa4ce67e 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/migration_tests.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/migration_tests.rs @@ -4,8 +4,9 @@ use cw_multi_test::{next_block, App, Executor}; use cw_utils::Duration; use dao_interface::query::{GetItemResponse, ProposalModuleCountResponse}; use dao_testing::contracts::{ - cw20_base_contract, cw20_stake_contract, cw20_staked_balances_voting_contract, - dao_dao_contract, proposal_single_contract, v1_dao_dao_contract, v1_proposal_single_contract, + cw20_base_contract, cw20_stake_contract, dao_dao_core_contract, dao_proposal_single_contract, + dao_voting_cw20_staked_contract, + v1::{cw_core_v1_contract, cw_proposal_single_v1_contract}, }; use dao_voting::veto::VetoConfig; use dao_voting::{ @@ -47,14 +48,14 @@ fn test_v1_v2_full_migration() { // instantiate a v1 DAO // ---- - let proposal_code = app.store_code(v1_proposal_single_contract()); - let core_code = app.store_code(v1_dao_dao_contract()); + let proposal_code = app.store_code(cw_proposal_single_v1_contract()); + let core_code = app.store_code(cw_core_v1_contract()); // cw20 staking and voting module has not changed across v1->v2 so // we use the current edition. let cw20_code = app.store_code(cw20_base_contract()); let cw20_stake_code = app.store_code(cw20_stake_contract()); - let voting_code = app.store_code(cw20_staked_balances_voting_contract()); + let voting_code = app.store_code(dao_voting_cw20_staked_contract()); let initial_balances = vec![Cw20Coin { address: sender.to_string(), @@ -300,8 +301,8 @@ fn test_v1_v2_full_migration() { // create a proposal to migrate to v2 // ---- - let v2_core_code = app.store_code(dao_dao_contract()); - let v2_proposal_code = app.store_code(proposal_single_contract()); + let v2_core_code = app.store_code(dao_dao_core_contract()); + let v2_proposal_code = app.store_code(dao_proposal_single_contract()); let pre_propose_info = get_pre_propose_info( &mut app, diff --git a/contracts/proposal/dao-proposal-single/src/testing/mod.rs b/contracts/proposal/dao-proposal-single/src/testing/mod.rs index 12c9b9af0..0eede537c 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/mod.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/mod.rs @@ -1,5 +1,4 @@ mod adversarial_tests; -mod contracts; mod do_votes; mod execute; mod instantiate; diff --git a/contracts/proposal/dao-proposal-single/src/testing/tests.rs b/contracts/proposal/dao-proposal-single/src/testing/tests.rs index 56bc68522..cfbe0b39d 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/tests.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/tests.rs @@ -16,7 +16,10 @@ use dao_interface::{ state::{Admin, ModuleInstantiateInfo}, voting::InfoResponse, }; -use dao_testing::{ShouldExecute, TestSingleChoiceVote}; +use dao_testing::{ + contracts::{dao_pre_propose_approval_single_contract, dao_proposal_single_contract}, + ShouldExecute, TestSingleChoiceVote, +}; use dao_voting::{ deposit::{CheckedDepositInfo, UncheckedDepositInfo, VotingModuleTokenType}, pre_propose::{PreProposeInfo, PreProposeSubmissionPolicy, ProposalCreationPolicy}, @@ -38,7 +41,6 @@ use crate::{ query::{ProposalResponse, VoteInfo}, state::Config, testing::{ - contracts::{pre_propose_single_contract, proposal_single_contract}, execute::{ add_proposal_hook, add_proposal_hook_should_fail, add_vote_hook, add_vote_hook_should_fail, close_proposal, close_proposal_should_fail, @@ -3092,7 +3094,7 @@ fn test_migrate_from_compatible() { proposal_id: _, } = setup_test(vec![]); - let new_code_id = app.store_code(proposal_single_contract()); + let new_code_id = app.store_code(dao_proposal_single_contract()); let start_config = query_proposal_config(&app, &proposal_module); app.execute( @@ -3154,8 +3156,8 @@ pub fn test_migrate_updates_version() { // let cw20_id = app.store_code(cw20_base_contract()); // let cw20_stake_id = app.store_code(cw20_stake_contract()); -// let staked_balances_voting_id = app.store_code(cw20_staked_balances_voting_contract()); -// let core_contract_id = app.store_code(cw_core_contract()); +// let staked_balances_voting_id = app.store_code(dao_voting_cw20_staked_contract()); +// let core_contract_id = app.store_code(dao_dao_core_contract()); // let instantiate_core = dao_interface::msg::InstantiateMsg { // admin: None, @@ -3278,8 +3280,8 @@ pub fn test_migrate_updates_version() { // ) // .unwrap(); -// let v2_proposal_single = app.store_code(proposal_single_contract()); -// let pre_propose_single = app.store_code(pre_propose_single_contract()); +// let v2_proposal_single = app.store_code(dao_proposal_single_contract()); +// let pre_propose_single = app.store_code(dao_pre_propose_approval_single_contract()); // // Attempt to migrate. This will fail as there is a pending // // proposal. @@ -3933,7 +3935,7 @@ fn test_update_pre_propose_module() { ProposalCreationPolicy::Module { addr } => addr, }; - let pre_propose_id = app.store_code(pre_propose_single_contract()); + let pre_propose_id = app.store_code(dao_pre_propose_approval_single_contract()); // Make a proposal to switch to a new pre-propose moudle. mint_cw20s(&mut app, &gov_token, &core_addr, CREATOR_ADDR, 10_000_000); diff --git a/contracts/staking/cw20-stake-external-rewards/Cargo.toml b/contracts/staking/cw20-stake-external-rewards/Cargo.toml index 9f59c261e..fc046976e 100644 --- a/contracts/staking/cw20-stake-external-rewards/Cargo.toml +++ b/contracts/staking/cw20-stake-external-rewards/Cargo.toml @@ -22,10 +22,10 @@ cw-storage-plus = { workspace = true } cw-controllers = { workspace = true } cw20 = { workspace = true } cw-utils = { workspace = true } -cw20-base = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } cw2 = { workspace = true } thiserror = { workspace = true } -cw20-stake = { workspace = true, features = ["library"]} +cw20-stake = { workspace = true, features = ["library"] } cw-ownable = { workspace = true } dao-hooks = { workspace = true } @@ -35,3 +35,4 @@ cw20-013 = { package = "cw20", version = "0.13" } [dev-dependencies] cw-multi-test = { workspace = true } anyhow = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/staking/cw20-stake-external-rewards/src/contract.rs b/contracts/staking/cw20-stake-external-rewards/src/contract.rs index e92b0b6d9..2faa57121 100644 --- a/contracts/staking/cw20-stake-external-rewards/src/contract.rs +++ b/contracts/staking/cw20-stake-external-rewards/src/contract.rs @@ -455,1583 +455,3 @@ pub fn query_pending_rewards( last_update_block: LAST_UPDATE_BLOCK.load(deps.storage).unwrap_or_default(), }) } - -#[cfg(test)] -mod tests { - use std::borrow::BorrowMut; - - use crate::{msg::MigrateMsg, ContractError}; - - use cosmwasm_std::{coin, to_json_binary, Addr, Empty, Uint128, WasmMsg}; - use cw20::{Cw20Coin, Cw20ExecuteMsg, Denom}; - use cw_ownable::{Action, Ownership, OwnershipError}; - use cw_utils::Duration; - - use cw_multi_test::{next_block, App, BankSudo, Contract, ContractWrapper, Executor, SudoMsg}; - - use cw20_stake_external_rewards_v1 as v1; - - use crate::msg::{ExecuteMsg, InfoResponse, PendingRewardsResponse, QueryMsg, ReceiveMsg}; - - const OWNER: &str = "owner"; - const ADDR1: &str = "addr0001"; - const ADDR2: &str = "addr0002"; - const ADDR3: &str = "addr0003"; - - pub fn contract_rewards() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_migrate(crate::contract::migrate); - Box::new(contract) - } - - pub fn contract_rewards_v1() -> Box> { - let contract = ContractWrapper::new( - v1::contract::execute, - v1::contract::instantiate, - v1::contract::query, - ); - Box::new(contract) - } - - pub fn contract_staking() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) - } - - pub fn contract_cw20() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) - } - - fn mock_app() -> App { - App::default() - } - - fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { - let cw20_id = app.store_code(contract_cw20()); - let msg = cw20_base::msg::InstantiateMsg { - name: String::from("Test"), - symbol: String::from("TEST"), - decimals: 6, - initial_balances, - mint: None, - marketing: None, - }; - - app.instantiate_contract(cw20_id, Addr::unchecked(ADDR1), &msg, &[], "cw20", None) - .unwrap() - } - - fn instantiate_staking( - app: &mut App, - cw20: Addr, - unstaking_duration: Option, - ) -> Addr { - let staking_code_id = app.store_code(contract_staking()); - let msg = cw20_stake::msg::InstantiateMsg { - owner: Some(OWNER.to_string()), - token_address: cw20.to_string(), - unstaking_duration, - }; - app.instantiate_contract( - staking_code_id, - Addr::unchecked(ADDR1), - &msg, - &[], - "staking", - None, - ) - .unwrap() - } - - fn stake_tokens>( - app: &mut App, - staking_addr: &Addr, - cw20_addr: &Addr, - sender: T, - amount: u128, - ) { - let msg = cw20::Cw20ExecuteMsg::Send { - contract: staking_addr.to_string(), - amount: Uint128::new(amount), - msg: to_json_binary(&cw20_stake::msg::ReceiveMsg::Stake {}).unwrap(), - }; - app.execute_contract(Addr::unchecked(sender), cw20_addr.clone(), &msg, &[]) - .unwrap(); - } - - fn unstake_tokens(app: &mut App, staking_addr: &Addr, address: &str, amount: u128) { - let msg = cw20_stake::msg::ExecuteMsg::Unstake { - amount: Uint128::new(amount), - }; - app.execute_contract(Addr::unchecked(address), staking_addr.clone(), &msg, &[]) - .unwrap(); - } - - fn setup_staking_contract(app: &mut App, initial_balances: Vec) -> (Addr, Addr) { - // Instantiate cw20 contract - let cw20_addr = instantiate_cw20(app, initial_balances.clone()); - app.update_block(next_block); - // Instantiate staking contract - let staking_addr = instantiate_staking(app, cw20_addr.clone(), None); - app.update_block(next_block); - for coin in initial_balances { - stake_tokens( - app, - &staking_addr, - &cw20_addr, - coin.address, - coin.amount.u128(), - ); - } - (staking_addr, cw20_addr) - } - - fn setup_reward_contract( - app: &mut App, - staking_contract: Addr, - reward_token: Denom, - owner: Addr, - ) -> Addr { - let reward_code_id = app.store_code(contract_rewards()); - let msg = crate::msg::InstantiateMsg { - owner: Some(owner.clone().into_string()), - staking_contract: staking_contract.clone().into_string(), - reward_token, - reward_duration: 100000, - }; - let reward_addr = app - .instantiate_contract(reward_code_id, owner, &msg, &[], "reward", None) - .unwrap(); - let msg = cw20_stake::msg::ExecuteMsg::AddHook { - addr: reward_addr.to_string(), - }; - let _result = app - .execute_contract(Addr::unchecked(OWNER), staking_contract, &msg, &[]) - .unwrap(); - reward_addr - } - - fn get_balance_cw20, U: Into>( - app: &App, - contract_addr: T, - address: U, - ) -> Uint128 { - let msg = cw20::Cw20QueryMsg::Balance { - address: address.into(), - }; - let result: cw20::BalanceResponse = - app.wrap().query_wasm_smart(contract_addr, &msg).unwrap(); - result.balance - } - - fn get_balance_native, U: Into>( - app: &App, - address: T, - denom: U, - ) -> Uint128 { - app.wrap().query_balance(address, denom).unwrap().amount - } - - fn get_ownership>(app: &App, address: T) -> Ownership { - app.wrap() - .query_wasm_smart(address, &QueryMsg::Ownership {}) - .unwrap() - } - - fn assert_pending_rewards(app: &mut App, reward_addr: &Addr, address: &str, expected: u128) { - let res: PendingRewardsResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart( - reward_addr, - &QueryMsg::GetPendingRewards { - address: address.to_string(), - }, - ) - .unwrap(); - assert_eq!(res.pending_rewards, Uint128::new(expected)); - } - - fn claim_rewards(app: &mut App, reward_addr: Addr, address: &str) { - let msg = ExecuteMsg::Claim {}; - app.borrow_mut() - .execute_contract(Addr::unchecked(address), reward_addr, &msg, &[]) - .unwrap(); - } - - fn fund_rewards_cw20( - app: &mut App, - admin: &Addr, - reward_token: Addr, - reward_addr: &Addr, - amount: u128, - ) { - let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); - let fund_msg = Cw20ExecuteMsg::Send { - contract: reward_addr.clone().into_string(), - amount: Uint128::new(amount), - msg: fund_sub_msg, - }; - let _res = app - .borrow_mut() - .execute_contract(admin.clone(), reward_token, &fund_msg, &[]) - .unwrap(); - } - - #[test] - fn test_zero_rewards_duration() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let denom = "utest".to_string(); - let (staking_addr, _) = setup_staking_contract(&mut app, vec![]); - let reward_funding = vec![coin(100000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding, - } - })) - .unwrap(); - - let reward_token = Denom::Native(denom); - let owner = admin; - let reward_code_id = app.store_code(contract_rewards()); - let msg = crate::msg::InstantiateMsg { - owner: Some(owner.clone().into_string()), - staking_contract: staking_addr.to_string(), - reward_token, - reward_duration: 0, - }; - let err: ContractError = app - .instantiate_contract(reward_code_id, owner, &msg, &[], "reward", None) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::ZeroRewardDuration {}) - } - - #[test] - fn test_native_rewards() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, cw20_addr) = setup_staking_contract(&mut app, initial_balances); - let reward_funding = vec![coin(100000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let reward_addr = setup_reward_contract( - &mut app, - staking_addr.clone(), - Denom::Native(denom.clone()), - admin.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - let _res = app - .borrow_mut() - .execute_contract( - admin.clone(), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(1000)); - assert_eq!(res.reward.period_finish, 101000); - assert_eq!(res.reward.reward_duration, 100000); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1500); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 750); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 750); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 2000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 1000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 1000); - - assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::zero()); - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::new(2000)); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); - - unstake_tokens(&mut app, &staking_addr, ADDR2, 50); - unstake_tokens(&mut app, &staking_addr, ADDR3, 50); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 15000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::new(17000)); - - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!(get_balance_native(&app, ADDR2, &denom), Uint128::new(3500)); - - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR2, 50); - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 50); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 6000); - - // Current height is 1034. ADDR1 is receiving 500 tokens/block - // and ADDR2 / ADDR3 are receiving 250. - // - // At height 101000 99966 additional blocks have passed. So we - // expect: - // - // ADDR1: 5000 + 99966 * 500 = 49,998,000 - // ADDR2: 2500 + 99966 * 250 = 24,994,000 - // ADDR3: 6000 + 99966 * 250 = 24,997,500 - app.borrow_mut().update_block(|b| b.height = 101000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 49988000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 24994000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 24997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!( - get_balance_native(&app, ADDR1, &denom), - Uint128::new(50005000) - ); - assert_eq!( - get_balance_native(&app, ADDR2, &denom), - Uint128::new(24997500) - ); - assert_eq!(get_balance_native(&app, ADDR3, &denom), Uint128::new(0)); - assert_eq!( - get_balance_native(&app, &reward_addr, &denom), - Uint128::new(24997500) - ); - - app.borrow_mut().update_block(|b| b.height = 200000); - let fund_msg = ExecuteMsg::Fund {}; - - // Add more rewards - let reward_funding = vec![coin(200000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - - let _res = app - .borrow_mut() - .execute_contract( - admin.clone(), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap(); - - app.borrow_mut().update_block(|b| b.height = 300000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 74997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!( - get_balance_native(&app, ADDR1, &denom), - Uint128::new(150005000) - ); - assert_eq!( - get_balance_native(&app, ADDR2, &denom), - Uint128::new(74997500) - ); - assert_eq!(get_balance_native(&app, ADDR3, &denom), Uint128::zero()); - assert_eq!( - get_balance_native(&app, &reward_addr, &denom), - Uint128::new(74997500) - ); - - // Add more rewards - let reward_funding = vec![coin(200000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - - let _res = app - .borrow_mut() - .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) - .unwrap(); - - app.borrow_mut().update_block(|b| b.height = 400000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 124997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - claim_rewards(&mut app, reward_addr.clone(), ADDR3); - assert_eq!( - get_balance_native(&app, ADDR1, &denom), - Uint128::new(250005000) - ); - assert_eq!( - get_balance_native(&app, ADDR2, &denom), - Uint128::new(124997500) - ); - assert_eq!( - get_balance_native(&app, ADDR3, &denom), - Uint128::new(124997500) - ); - assert_eq!( - get_balance_native(&app, &reward_addr, &denom), - Uint128::zero() - ); - - app.borrow_mut().update_block(|b| b.height = 500000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); - - app.borrow_mut().update_block(|b| b.height = 1000000); - unstake_tokens(&mut app, &staking_addr, ADDR3, 1); - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 1); - } - - #[test] - fn test_cw20_rewards() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, cw20_addr) = setup_staking_contract(&mut app, initial_balances); - let reward_token = instantiate_cw20( - &mut app, - vec![Cw20Coin { - address: OWNER.to_string(), - amount: Uint128::new(500000000), - }], - ); - let reward_addr = setup_reward_contract( - &mut app, - staking_addr.clone(), - Denom::Cw20(reward_token.clone()), - admin.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - fund_rewards_cw20( - &mut app, - &admin, - reward_token.clone(), - &reward_addr, - 100000000, - ); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(1000)); - assert_eq!(res.reward.period_finish, 101000); - assert_eq!(res.reward.reward_duration, 100000); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1500); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 750); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 750); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 2000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 1000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 1000); - - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::zero() - ); - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::new(2000) - ); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); - - unstake_tokens(&mut app, &staking_addr, ADDR2, 50); - unstake_tokens(&mut app, &staking_addr, ADDR3, 50); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 15000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::new(17000) - ); - - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR2), - Uint128::new(3500) - ); - - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR2, 50); - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 50); - - app.borrow_mut().update_block(|b| b.height += 10); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 6000); - - app.borrow_mut().update_block(|b| b.height = 101000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 49988000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 24994000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 24997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::new(50005000) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR2), - Uint128::new(24997500) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR3), - Uint128::new(0) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, &reward_addr), - Uint128::new(24997500) - ); - - app.borrow_mut().update_block(|b| b.height = 200000); - - let reward_funding = vec![coin(200000000, denom)]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding, - } - })) - .unwrap(); - - fund_rewards_cw20( - &mut app, - &admin, - reward_token.clone(), - &reward_addr, - 200000000, - ); - - app.borrow_mut().update_block(|b| b.height = 300000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 74997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::new(150005000) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR2), - Uint128::new(74997500) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR3), - Uint128::zero() - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, &reward_addr), - Uint128::new(74997500) - ); - - // Add more rewards - fund_rewards_cw20( - &mut app, - &admin, - reward_token.clone(), - &reward_addr, - 200000000, - ); - - app.borrow_mut().update_block(|b| b.height = 400000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 124997500); - - claim_rewards(&mut app, reward_addr.clone(), ADDR1); - claim_rewards(&mut app, reward_addr.clone(), ADDR2); - claim_rewards(&mut app, reward_addr.clone(), ADDR3); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR1), - Uint128::new(250005000) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR2), - Uint128::new(124997500) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, ADDR3), - Uint128::new(124997500) - ); - assert_eq!( - get_balance_cw20(&app, &reward_token, &reward_addr), - Uint128::zero() - ); - - app.borrow_mut().update_block(|b| b.height = 500000); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); - - app.borrow_mut().update_block(|b| b.height = 1000000); - unstake_tokens(&mut app, &staking_addr, ADDR3, 1); - stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 1); - } - - #[test] - fn update_rewards() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); - let reward_funding = vec![coin(200000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - // Add funding to Addr1 to make sure it can't update staking contract - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: ADDR1.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let reward_addr = setup_reward_contract( - &mut app, - staking_addr, - Denom::Native(denom.clone()), - admin.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - // None admin cannot update rewards - let err: ContractError = app - .borrow_mut() - .execute_contract( - Addr::unchecked(ADDR1), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap_err() - .downcast() - .unwrap(); - - assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); - - let _res = app - .borrow_mut() - .execute_contract( - admin.clone(), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(2000)); - assert_eq!(res.reward.period_finish, 101000); - assert_eq!(res.reward.reward_duration, 100000); - - // Create new period after old period - app.borrow_mut().update_block(|b| b.height = 101000); - - let reward_funding = vec![coin(100000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let _res = app - .borrow_mut() - .execute_contract( - admin.clone(), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(1000)); - assert_eq!(res.reward.period_finish, 201000); - assert_eq!(res.reward.reward_duration, 100000); - - // Add funds in middle of period returns an error - app.borrow_mut().update_block(|b| b.height = 151000); - - let reward_funding = vec![coin(200000000, denom)]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let err = app - .borrow_mut() - .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) - .unwrap_err(); - assert_eq!( - ContractError::RewardPeriodNotFinished {}, - err.downcast().unwrap() - ); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(1000)); - assert_eq!(res.reward.period_finish, 201000); - assert_eq!(res.reward.reward_duration, 100000); - } - - #[test] - fn update_reward_duration() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); - - let reward_addr = setup_reward_contract( - &mut app, - staking_addr, - Denom::Native(denom.clone()), - admin.clone(), - ); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(0)); - assert_eq!(res.reward.period_finish, 0); - assert_eq!(res.reward.reward_duration, 100000); - - // Zero rewards durations are not allowed. - let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 0 }; - let err: ContractError = app - .borrow_mut() - .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::ZeroRewardDuration {}); - - let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 10 }; - let _resp = app - .borrow_mut() - .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(0)); - assert_eq!(res.reward.period_finish, 0); - assert_eq!(res.reward.reward_duration, 10); - - // Non-admin cannot update rewards - let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 100 }; - let err: ContractError = app - .borrow_mut() - .execute_contract(Addr::unchecked("non-admin"), reward_addr.clone(), &msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); - - let reward_funding = vec![coin(1000, denom)]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - // Add funding to Addr1 to make sure it can't update staking contract - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: ADDR1.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - let _res = app - .borrow_mut() - .execute_contract( - admin.clone(), - reward_addr.clone(), - &fund_msg, - &reward_funding, - ) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(100)); - assert_eq!(res.reward.period_finish, 1010); - assert_eq!(res.reward.reward_duration, 10); - - // Cannot update reward period before it finishes - let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 10 }; - let err: ContractError = app - .borrow_mut() - .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::RewardPeriodNotFinished {}); - - // Update reward period once rewards are finished - app.borrow_mut().update_block(|b| b.height = 1010); - - let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 100 }; - let _resp = app - .borrow_mut() - .execute_contract(admin, reward_addr.clone(), &msg, &[]) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(100)); - assert_eq!(res.reward.period_finish, 1010); - assert_eq!(res.reward.reward_duration, 100); - } - - #[test] - fn test_update_owner() { - let mut app = mock_app(); - let addr_owner = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); - - let reward_addr = setup_reward_contract( - &mut app, - staking_addr, - Denom::Native(denom), - addr_owner.clone(), - ); - - let owner = get_ownership(&app, &reward_addr).owner; - assert_eq!(owner, Some(addr_owner.clone())); - - // random addr cannot update owner - let msg = ExecuteMsg::UpdateOwnership(Action::TransferOwnership { - new_owner: ADDR1.to_string(), - expiry: None, - }); - let err: ContractError = app - .borrow_mut() - .execute_contract(Addr::unchecked(ADDR1), reward_addr.clone(), &msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); - - // owner nominates a new onwer. - app.borrow_mut() - .execute_contract(addr_owner.clone(), reward_addr.clone(), &msg, &[]) - .unwrap(); - - let ownership = get_ownership(&app, &reward_addr); - assert_eq!( - ownership, - Ownership:: { - owner: Some(addr_owner), - pending_owner: Some(Addr::unchecked(ADDR1)), - pending_expiry: None, - } - ); - - // new owner accepts the nomination. - app.execute_contract( - Addr::unchecked(ADDR1), - reward_addr.clone(), - &ExecuteMsg::UpdateOwnership(Action::AcceptOwnership), - &[], - ) - .unwrap(); - - let ownership = get_ownership(&app, &reward_addr); - assert_eq!( - ownership, - Ownership:: { - owner: Some(Addr::unchecked(ADDR1)), - pending_owner: None, - pending_expiry: None, - } - ); - - // new owner renounces ownership. - app.execute_contract( - Addr::unchecked(ADDR1), - reward_addr.clone(), - &ExecuteMsg::UpdateOwnership(Action::RenounceOwnership), - &[], - ) - .unwrap(); - - let ownership = get_ownership(&app, &reward_addr); - assert_eq!( - ownership, - Ownership:: { - owner: None, - pending_owner: None, - pending_expiry: None, - } - ); - } - - #[test] - fn test_cannot_fund_with_wrong_coin_native() { - let mut app = mock_app(); - let owner = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); - - let reward_addr = setup_reward_contract( - &mut app, - staking_addr, - Denom::Native(denom.clone()), - owner.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - // No funding - let fund_msg = ExecuteMsg::Fund {}; - - let err: ContractError = app - .borrow_mut() - .execute_contract(owner.clone(), reward_addr.clone(), &fund_msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidFunds {}); - - // Invalid funding - let invalid_funding = vec![coin(100, "invalid")]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: owner.to_string(), - amount: invalid_funding.clone(), - } - })) - .unwrap(); - - let fund_msg = ExecuteMsg::Fund {}; - - let err: ContractError = app - .borrow_mut() - .execute_contract( - owner.clone(), - reward_addr.clone(), - &fund_msg, - &invalid_funding, - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidFunds {}); - - // Extra funding - let extra_funding = vec![coin(100, denom), coin(100, "extra")]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: owner.to_string(), - amount: extra_funding.clone(), - } - })) - .unwrap(); - - let fund_msg = ExecuteMsg::Fund {}; - - let err: ContractError = app - .borrow_mut() - .execute_contract( - owner.clone(), - reward_addr.clone(), - &fund_msg, - &extra_funding, - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidFunds {}); - - // Cw20 funding fails - let cw20_token = instantiate_cw20( - &mut app, - vec![Cw20Coin { - address: OWNER.to_string(), - amount: Uint128::new(500000000), - }], - ); - let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); - let fund_msg = Cw20ExecuteMsg::Send { - contract: reward_addr.into_string(), - amount: Uint128::new(100), - msg: fund_sub_msg, - }; - let err: ContractError = app - .borrow_mut() - .execute_contract(owner, cw20_token, &fund_msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidCw20 {}); - } - - #[test] - fn test_cannot_fund_with_wrong_coin_cw20() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let _denom = "utest".to_string(); - let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); - let reward_token = instantiate_cw20( - &mut app, - vec![Cw20Coin { - address: OWNER.to_string(), - amount: Uint128::new(500000000), - }], - ); - let reward_addr = setup_reward_contract( - &mut app, - staking_addr, - Denom::Cw20(Addr::unchecked("dummy_cw20")), - admin.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - // Test with invalid token - let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); - let fund_msg = Cw20ExecuteMsg::Send { - contract: reward_addr.clone().into_string(), - amount: Uint128::new(100), - msg: fund_sub_msg, - }; - let err: ContractError = app - .borrow_mut() - .execute_contract(admin.clone(), reward_token, &fund_msg, &[]) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidCw20 {}); - - // Test does not work when funded with native - let invalid_funding = vec![coin(100, "invalid")]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: invalid_funding.clone(), - } - })) - .unwrap(); - - let fund_msg = ExecuteMsg::Fund {}; - - let err: ContractError = app - .borrow_mut() - .execute_contract(admin, reward_addr, &fund_msg, &invalid_funding) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::InvalidFunds {}) - } - - #[test] - fn test_rewards_with_zero_staked() { - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - // Instantiate cw20 contract - let cw20_addr = instantiate_cw20(&mut app, initial_balances.clone()); - app.update_block(next_block); - // Instantiate staking contract - let staking_addr = instantiate_staking(&mut app, cw20_addr.clone(), None); - app.update_block(next_block); - let reward_funding = vec![coin(100000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let reward_addr = setup_reward_contract( - &mut app, - staking_addr.clone(), - Denom::Native(denom), - admin.clone(), - ); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - let _res = app - .borrow_mut() - .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(1000)); - assert_eq!(res.reward.period_finish, 101000); - assert_eq!(res.reward.reward_duration, 100000); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); - - for coin in initial_balances { - stake_tokens( - &mut app, - &staking_addr, - &cw20_addr, - coin.address, - coin.amount.u128(), - ); - } - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); - } - - #[test] - fn test_small_rewards() { - // This test was added due to a bug in the contract not properly paying out small reward - // amounts due to floor division - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); - let reward_funding = vec![coin(1000000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let reward_addr = - setup_reward_contract(&mut app, staking_addr, Denom::Native(denom), admin.clone()); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - let _res = app - .borrow_mut() - .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) - .unwrap(); - - let res: InfoResponse = app - .borrow_mut() - .wrap() - .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) - .unwrap(); - - assert_eq!(res.reward.reward_rate, Uint128::new(10)); - assert_eq!(res.reward.period_finish, 101000); - assert_eq!(res.reward.reward_duration, 100000); - - app.borrow_mut().update_block(next_block); - assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5); - assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2); - assert_pending_rewards(&mut app, &reward_addr, ADDR3, 2); - } - - #[test] - fn test_zero_reward_rate_failed() { - // This test is due to a bug when funder provides rewards config that results in less then 1 - // reward per block which rounds down to zer0 - let mut app = mock_app(); - let admin = Addr::unchecked(OWNER); - app.borrow_mut().update_block(|b| b.height = 0); - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); - let reward_funding = vec![coin(10000, denom.clone())]; - app.sudo(SudoMsg::Bank({ - BankSudo::Mint { - to_address: admin.to_string(), - amount: reward_funding.clone(), - } - })) - .unwrap(); - let reward_addr = - setup_reward_contract(&mut app, staking_addr, Denom::Native(denom), admin.clone()); - - app.borrow_mut().update_block(|b| b.height = 1000); - - let fund_msg = ExecuteMsg::Fund {}; - - let _res = app - .borrow_mut() - .execute_contract(admin, reward_addr, &fund_msg, &reward_funding) - .unwrap_err(); - } - - #[test] - fn test_migrate_from_v1() { - let mut app = App::default(); - - let v1_code = app.store_code(contract_rewards_v1()); - let v2_code = app.store_code(contract_rewards()); - - let initial_balances = vec![ - Cw20Coin { - address: ADDR1.to_string(), - amount: Uint128::new(100), - }, - Cw20Coin { - address: ADDR2.to_string(), - amount: Uint128::new(50), - }, - Cw20Coin { - address: ADDR3.to_string(), - amount: Uint128::new(50), - }, - ]; - let denom = "utest".to_string(); - let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); - - let rewards_addr = app - .instantiate_contract( - v1_code, - Addr::unchecked(OWNER), - &v1::msg::InstantiateMsg { - owner: Some(OWNER.to_string()), - manager: Some(ADDR1.to_string()), - staking_contract: staking_addr.into_string(), - reward_token: cw20_013::Denom::Native(denom), - reward_duration: 10000, - }, - &[], - "rewards".to_string(), - Some(OWNER.to_string()), - ) - .unwrap(); - - app.execute( - Addr::unchecked(OWNER), - WasmMsg::Migrate { - contract_addr: rewards_addr.to_string(), - new_code_id: v2_code, - msg: to_json_binary(&MigrateMsg::FromV1 {}).unwrap(), - } - .into(), - ) - .unwrap(); - - let ownership = get_ownership(&app, &rewards_addr); - assert_eq!( - ownership, - Ownership:: { - owner: Some(Addr::unchecked(OWNER)), - pending_owner: None, - pending_expiry: None, - } - ); - - let err: ContractError = app - .execute( - Addr::unchecked(OWNER), - WasmMsg::Migrate { - contract_addr: rewards_addr.to_string(), - new_code_id: v2_code, - msg: to_json_binary(&MigrateMsg::FromV1 {}).unwrap(), - } - .into(), - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, ContractError::AlreadyMigrated {}); - } -} diff --git a/contracts/staking/cw20-stake-external-rewards/src/lib.rs b/contracts/staking/cw20-stake-external-rewards/src/lib.rs index 595daabe0..62c64328d 100644 --- a/contracts/staking/cw20-stake-external-rewards/src/lib.rs +++ b/contracts/staking/cw20-stake-external-rewards/src/lib.rs @@ -6,3 +6,6 @@ pub mod msg; pub mod state; pub use crate::error::ContractError; + +#[cfg(test)] +mod tests; diff --git a/contracts/staking/cw20-stake-external-rewards/src/tests.rs b/contracts/staking/cw20-stake-external-rewards/src/tests.rs new file mode 100644 index 000000000..d0e00d4b6 --- /dev/null +++ b/contracts/staking/cw20-stake-external-rewards/src/tests.rs @@ -0,0 +1,1537 @@ +use std::borrow::BorrowMut; + +use cosmwasm_std::{coin, to_json_binary, Addr, Uint128, WasmMsg}; +use cw20::{Cw20Coin, Cw20ExecuteMsg, Denom}; +use cw20_stake_external_rewards_v1 as v1; +use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; +use cw_ownable::{Action, Ownership, OwnershipError}; +use cw_utils::Duration; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, cw20_stake_external_rewards_contract, + v1::cw20_stake_external_rewards_v1_contract, +}; + +use crate::{ + msg::{ExecuteMsg, InfoResponse, MigrateMsg, PendingRewardsResponse, QueryMsg, ReceiveMsg}, + ContractError, +}; + +const OWNER: &str = "owner"; +const ADDR1: &str = "addr0001"; +const ADDR2: &str = "addr0002"; +const ADDR3: &str = "addr0003"; + +fn mock_app() -> App { + App::default() +} + +fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { + let cw20_id = app.store_code(cw20_base_contract()); + let msg = cw20_base::msg::InstantiateMsg { + name: String::from("Test"), + symbol: String::from("TEST"), + decimals: 6, + initial_balances, + mint: None, + marketing: None, + }; + + app.instantiate_contract(cw20_id, Addr::unchecked(ADDR1), &msg, &[], "cw20", None) + .unwrap() +} + +fn instantiate_staking(app: &mut App, cw20: Addr, unstaking_duration: Option) -> Addr { + let staking_code_id = app.store_code(cw20_stake_contract()); + let msg = cw20_stake::msg::InstantiateMsg { + owner: Some(OWNER.to_string()), + token_address: cw20.to_string(), + unstaking_duration, + }; + app.instantiate_contract( + staking_code_id, + Addr::unchecked(ADDR1), + &msg, + &[], + "staking", + None, + ) + .unwrap() +} + +fn stake_tokens>( + app: &mut App, + staking_addr: &Addr, + cw20_addr: &Addr, + sender: T, + amount: u128, +) { + let msg = cw20::Cw20ExecuteMsg::Send { + contract: staking_addr.to_string(), + amount: Uint128::new(amount), + msg: to_json_binary(&cw20_stake::msg::ReceiveMsg::Stake {}).unwrap(), + }; + app.execute_contract(Addr::unchecked(sender), cw20_addr.clone(), &msg, &[]) + .unwrap(); +} + +fn unstake_tokens(app: &mut App, staking_addr: &Addr, address: &str, amount: u128) { + let msg = cw20_stake::msg::ExecuteMsg::Unstake { + amount: Uint128::new(amount), + }; + app.execute_contract(Addr::unchecked(address), staking_addr.clone(), &msg, &[]) + .unwrap(); +} + +fn setup_staking_contract(app: &mut App, initial_balances: Vec) -> (Addr, Addr) { + // Instantiate cw20 contract + let cw20_addr = instantiate_cw20(app, initial_balances.clone()); + app.update_block(next_block); + // Instantiate staking contract + let staking_addr = instantiate_staking(app, cw20_addr.clone(), None); + app.update_block(next_block); + for coin in initial_balances { + stake_tokens( + app, + &staking_addr, + &cw20_addr, + coin.address, + coin.amount.u128(), + ); + } + (staking_addr, cw20_addr) +} + +fn setup_reward_contract( + app: &mut App, + staking_contract: Addr, + reward_token: Denom, + owner: Addr, +) -> Addr { + let reward_code_id = app.store_code(cw20_stake_external_rewards_contract()); + let msg = crate::msg::InstantiateMsg { + owner: Some(owner.clone().into_string()), + staking_contract: staking_contract.clone().into_string(), + reward_token, + reward_duration: 100000, + }; + let reward_addr = app + .instantiate_contract(reward_code_id, owner, &msg, &[], "reward", None) + .unwrap(); + let msg = cw20_stake::msg::ExecuteMsg::AddHook { + addr: reward_addr.to_string(), + }; + let _result = app + .execute_contract(Addr::unchecked(OWNER), staking_contract, &msg, &[]) + .unwrap(); + reward_addr +} + +fn get_balance_cw20, U: Into>( + app: &App, + contract_addr: T, + address: U, +) -> Uint128 { + let msg = cw20::Cw20QueryMsg::Balance { + address: address.into(), + }; + let result: cw20::BalanceResponse = app.wrap().query_wasm_smart(contract_addr, &msg).unwrap(); + result.balance +} + +fn get_balance_native, U: Into>( + app: &App, + address: T, + denom: U, +) -> Uint128 { + app.wrap().query_balance(address, denom).unwrap().amount +} + +fn get_ownership>(app: &App, address: T) -> Ownership { + app.wrap() + .query_wasm_smart(address, &QueryMsg::Ownership {}) + .unwrap() +} + +fn assert_pending_rewards(app: &mut App, reward_addr: &Addr, address: &str, expected: u128) { + let res: PendingRewardsResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart( + reward_addr, + &QueryMsg::GetPendingRewards { + address: address.to_string(), + }, + ) + .unwrap(); + assert_eq!(res.pending_rewards, Uint128::new(expected)); +} + +fn claim_rewards(app: &mut App, reward_addr: Addr, address: &str) { + let msg = ExecuteMsg::Claim {}; + app.borrow_mut() + .execute_contract(Addr::unchecked(address), reward_addr, &msg, &[]) + .unwrap(); +} + +fn fund_rewards_cw20( + app: &mut App, + admin: &Addr, + reward_token: Addr, + reward_addr: &Addr, + amount: u128, +) { + let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); + let fund_msg = Cw20ExecuteMsg::Send { + contract: reward_addr.clone().into_string(), + amount: Uint128::new(amount), + msg: fund_sub_msg, + }; + let _res = app + .borrow_mut() + .execute_contract(admin.clone(), reward_token, &fund_msg, &[]) + .unwrap(); +} + +#[test] +fn test_zero_rewards_duration() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let denom = "utest".to_string(); + let (staking_addr, _) = setup_staking_contract(&mut app, vec![]); + let reward_funding = vec![coin(100000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding, + } + })) + .unwrap(); + + let reward_token = Denom::Native(denom); + let owner = admin; + let reward_code_id = app.store_code(cw20_stake_external_rewards_contract()); + let msg = crate::msg::InstantiateMsg { + owner: Some(owner.clone().into_string()), + staking_contract: staking_addr.to_string(), + reward_token, + reward_duration: 0, + }; + let err: ContractError = app + .instantiate_contract(reward_code_id, owner, &msg, &[], "reward", None) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::ZeroRewardDuration {}) +} + +#[test] +fn test_native_rewards() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, cw20_addr) = setup_staking_contract(&mut app, initial_balances); + let reward_funding = vec![coin(100000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let reward_addr = setup_reward_contract( + &mut app, + staking_addr.clone(), + Denom::Native(denom.clone()), + admin.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + let _res = app + .borrow_mut() + .execute_contract( + admin.clone(), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(1000)); + assert_eq!(res.reward.period_finish, 101000); + assert_eq!(res.reward.reward_duration, 100000); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1500); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 750); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 750); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 2000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 1000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 1000); + + assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::zero()); + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::new(2000)); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); + + unstake_tokens(&mut app, &staking_addr, ADDR2, 50); + unstake_tokens(&mut app, &staking_addr, ADDR3, 50); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 15000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + assert_eq!(get_balance_native(&app, ADDR1, &denom), Uint128::new(17000)); + + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!(get_balance_native(&app, ADDR2, &denom), Uint128::new(3500)); + + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR2, 50); + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 50); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 6000); + + // Current height is 1034. ADDR1 is receiving 500 tokens/block + // and ADDR2 / ADDR3 are receiving 250. + // + // At height 101000 99966 additional blocks have passed. So we + // expect: + // + // ADDR1: 5000 + 99966 * 500 = 49,998,000 + // ADDR2: 2500 + 99966 * 250 = 24,994,000 + // ADDR3: 6000 + 99966 * 250 = 24,997,500 + app.borrow_mut().update_block(|b| b.height = 101000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 49988000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 24994000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 24997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!( + get_balance_native(&app, ADDR1, &denom), + Uint128::new(50005000) + ); + assert_eq!( + get_balance_native(&app, ADDR2, &denom), + Uint128::new(24997500) + ); + assert_eq!(get_balance_native(&app, ADDR3, &denom), Uint128::new(0)); + assert_eq!( + get_balance_native(&app, &reward_addr, &denom), + Uint128::new(24997500) + ); + + app.borrow_mut().update_block(|b| b.height = 200000); + let fund_msg = ExecuteMsg::Fund {}; + + // Add more rewards + let reward_funding = vec![coin(200000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + + let _res = app + .borrow_mut() + .execute_contract( + admin.clone(), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap(); + + app.borrow_mut().update_block(|b| b.height = 300000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 74997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!( + get_balance_native(&app, ADDR1, &denom), + Uint128::new(150005000) + ); + assert_eq!( + get_balance_native(&app, ADDR2, &denom), + Uint128::new(74997500) + ); + assert_eq!(get_balance_native(&app, ADDR3, &denom), Uint128::zero()); + assert_eq!( + get_balance_native(&app, &reward_addr, &denom), + Uint128::new(74997500) + ); + + // Add more rewards + let reward_funding = vec![coin(200000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + + let _res = app + .borrow_mut() + .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) + .unwrap(); + + app.borrow_mut().update_block(|b| b.height = 400000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 124997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + claim_rewards(&mut app, reward_addr.clone(), ADDR3); + assert_eq!( + get_balance_native(&app, ADDR1, &denom), + Uint128::new(250005000) + ); + assert_eq!( + get_balance_native(&app, ADDR2, &denom), + Uint128::new(124997500) + ); + assert_eq!( + get_balance_native(&app, ADDR3, &denom), + Uint128::new(124997500) + ); + assert_eq!( + get_balance_native(&app, &reward_addr, &denom), + Uint128::zero() + ); + + app.borrow_mut().update_block(|b| b.height = 500000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); + + app.borrow_mut().update_block(|b| b.height = 1000000); + unstake_tokens(&mut app, &staking_addr, ADDR3, 1); + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 1); +} + +#[test] +fn test_cw20_rewards() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, cw20_addr) = setup_staking_contract(&mut app, initial_balances); + let reward_token = instantiate_cw20( + &mut app, + vec![Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(500000000), + }], + ); + let reward_addr = setup_reward_contract( + &mut app, + staking_addr.clone(), + Denom::Cw20(reward_token.clone()), + admin.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + fund_rewards_cw20( + &mut app, + &admin, + reward_token.clone(), + &reward_addr, + 100000000, + ); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(1000)); + assert_eq!(res.reward.period_finish, 101000); + assert_eq!(res.reward.reward_duration, 100000); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1500); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 750); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 750); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 2000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 1000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 1000); + + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::zero() + ); + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::new(2000) + ); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); + + unstake_tokens(&mut app, &staking_addr, ADDR2, 50); + unstake_tokens(&mut app, &staking_addr, ADDR3, 50); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 15000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 3500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 3500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::new(17000) + ); + + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR2), + Uint128::new(3500) + ); + + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR2, 50); + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 50); + + app.borrow_mut().update_block(|b| b.height += 10); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 6000); + + app.borrow_mut().update_block(|b| b.height = 101000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 49988000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 24994000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 24997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::new(50005000) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR2), + Uint128::new(24997500) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR3), + Uint128::new(0) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, &reward_addr), + Uint128::new(24997500) + ); + + app.borrow_mut().update_block(|b| b.height = 200000); + + let reward_funding = vec![coin(200000000, denom)]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding, + } + })) + .unwrap(); + + fund_rewards_cw20( + &mut app, + &admin, + reward_token.clone(), + &reward_addr, + 200000000, + ); + + app.borrow_mut().update_block(|b| b.height = 300000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 74997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::new(150005000) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR2), + Uint128::new(74997500) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR3), + Uint128::zero() + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, &reward_addr), + Uint128::new(74997500) + ); + + // Add more rewards + fund_rewards_cw20( + &mut app, + &admin, + reward_token.clone(), + &reward_addr, + 200000000, + ); + + app.borrow_mut().update_block(|b| b.height = 400000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 100000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 50000000); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 124997500); + + claim_rewards(&mut app, reward_addr.clone(), ADDR1); + claim_rewards(&mut app, reward_addr.clone(), ADDR2); + claim_rewards(&mut app, reward_addr.clone(), ADDR3); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR1), + Uint128::new(250005000) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR2), + Uint128::new(124997500) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, ADDR3), + Uint128::new(124997500) + ); + assert_eq!( + get_balance_cw20(&app, &reward_token, &reward_addr), + Uint128::zero() + ); + + app.borrow_mut().update_block(|b| b.height = 500000); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); + + app.borrow_mut().update_block(|b| b.height = 1000000); + unstake_tokens(&mut app, &staking_addr, ADDR3, 1); + stake_tokens(&mut app, &staking_addr, &cw20_addr, ADDR3, 1); +} + +#[test] +fn update_rewards() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); + let reward_funding = vec![coin(200000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + // Add funding to Addr1 to make sure it can't update staking contract + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: ADDR1.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let reward_addr = setup_reward_contract( + &mut app, + staking_addr, + Denom::Native(denom.clone()), + admin.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + // None admin cannot update rewards + let err: ContractError = app + .borrow_mut() + .execute_contract( + Addr::unchecked(ADDR1), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); + + let _res = app + .borrow_mut() + .execute_contract( + admin.clone(), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(2000)); + assert_eq!(res.reward.period_finish, 101000); + assert_eq!(res.reward.reward_duration, 100000); + + // Create new period after old period + app.borrow_mut().update_block(|b| b.height = 101000); + + let reward_funding = vec![coin(100000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let _res = app + .borrow_mut() + .execute_contract( + admin.clone(), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(1000)); + assert_eq!(res.reward.period_finish, 201000); + assert_eq!(res.reward.reward_duration, 100000); + + // Add funds in middle of period returns an error + app.borrow_mut().update_block(|b| b.height = 151000); + + let reward_funding = vec![coin(200000000, denom)]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let err = app + .borrow_mut() + .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) + .unwrap_err(); + assert_eq!( + ContractError::RewardPeriodNotFinished {}, + err.downcast().unwrap() + ); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(1000)); + assert_eq!(res.reward.period_finish, 201000); + assert_eq!(res.reward.reward_duration, 100000); +} + +#[test] +fn update_reward_duration() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); + + let reward_addr = setup_reward_contract( + &mut app, + staking_addr, + Denom::Native(denom.clone()), + admin.clone(), + ); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(0)); + assert_eq!(res.reward.period_finish, 0); + assert_eq!(res.reward.reward_duration, 100000); + + // Zero rewards durations are not allowed. + let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 0 }; + let err: ContractError = app + .borrow_mut() + .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::ZeroRewardDuration {}); + + let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 10 }; + let _resp = app + .borrow_mut() + .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(0)); + assert_eq!(res.reward.period_finish, 0); + assert_eq!(res.reward.reward_duration, 10); + + // Non-admin cannot update rewards + let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 100 }; + let err: ContractError = app + .borrow_mut() + .execute_contract(Addr::unchecked("non-admin"), reward_addr.clone(), &msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); + + let reward_funding = vec![coin(1000, denom)]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + // Add funding to Addr1 to make sure it can't update staking contract + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: ADDR1.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + let _res = app + .borrow_mut() + .execute_contract( + admin.clone(), + reward_addr.clone(), + &fund_msg, + &reward_funding, + ) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(100)); + assert_eq!(res.reward.period_finish, 1010); + assert_eq!(res.reward.reward_duration, 10); + + // Cannot update reward period before it finishes + let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 10 }; + let err: ContractError = app + .borrow_mut() + .execute_contract(admin.clone(), reward_addr.clone(), &msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::RewardPeriodNotFinished {}); + + // Update reward period once rewards are finished + app.borrow_mut().update_block(|b| b.height = 1010); + + let msg = ExecuteMsg::UpdateRewardDuration { new_duration: 100 }; + let _resp = app + .borrow_mut() + .execute_contract(admin, reward_addr.clone(), &msg, &[]) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(100)); + assert_eq!(res.reward.period_finish, 1010); + assert_eq!(res.reward.reward_duration, 100); +} + +#[test] +fn test_update_owner() { + let mut app = mock_app(); + let addr_owner = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); + + let reward_addr = setup_reward_contract( + &mut app, + staking_addr, + Denom::Native(denom), + addr_owner.clone(), + ); + + let owner = get_ownership(&app, &reward_addr).owner; + assert_eq!(owner, Some(addr_owner.clone())); + + // random addr cannot update owner + let msg = ExecuteMsg::UpdateOwnership(Action::TransferOwnership { + new_owner: ADDR1.to_string(), + expiry: None, + }); + let err: ContractError = app + .borrow_mut() + .execute_contract(Addr::unchecked(ADDR1), reward_addr.clone(), &msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Ownable(OwnershipError::NotOwner)); + + // owner nominates a new onwer. + app.borrow_mut() + .execute_contract(addr_owner.clone(), reward_addr.clone(), &msg, &[]) + .unwrap(); + + let ownership = get_ownership(&app, &reward_addr); + assert_eq!( + ownership, + Ownership:: { + owner: Some(addr_owner), + pending_owner: Some(Addr::unchecked(ADDR1)), + pending_expiry: None, + } + ); + + // new owner accepts the nomination. + app.execute_contract( + Addr::unchecked(ADDR1), + reward_addr.clone(), + &ExecuteMsg::UpdateOwnership(Action::AcceptOwnership), + &[], + ) + .unwrap(); + + let ownership = get_ownership(&app, &reward_addr); + assert_eq!( + ownership, + Ownership:: { + owner: Some(Addr::unchecked(ADDR1)), + pending_owner: None, + pending_expiry: None, + } + ); + + // new owner renounces ownership. + app.execute_contract( + Addr::unchecked(ADDR1), + reward_addr.clone(), + &ExecuteMsg::UpdateOwnership(Action::RenounceOwnership), + &[], + ) + .unwrap(); + + let ownership = get_ownership(&app, &reward_addr); + assert_eq!( + ownership, + Ownership:: { + owner: None, + pending_owner: None, + pending_expiry: None, + } + ); +} + +#[test] +fn test_cannot_fund_with_wrong_coin_native() { + let mut app = mock_app(); + let owner = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); + + let reward_addr = setup_reward_contract( + &mut app, + staking_addr, + Denom::Native(denom.clone()), + owner.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + // No funding + let fund_msg = ExecuteMsg::Fund {}; + + let err: ContractError = app + .borrow_mut() + .execute_contract(owner.clone(), reward_addr.clone(), &fund_msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidFunds {}); + + // Invalid funding + let invalid_funding = vec![coin(100, "invalid")]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: owner.to_string(), + amount: invalid_funding.clone(), + } + })) + .unwrap(); + + let fund_msg = ExecuteMsg::Fund {}; + + let err: ContractError = app + .borrow_mut() + .execute_contract( + owner.clone(), + reward_addr.clone(), + &fund_msg, + &invalid_funding, + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidFunds {}); + + // Extra funding + let extra_funding = vec![coin(100, denom), coin(100, "extra")]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: owner.to_string(), + amount: extra_funding.clone(), + } + })) + .unwrap(); + + let fund_msg = ExecuteMsg::Fund {}; + + let err: ContractError = app + .borrow_mut() + .execute_contract( + owner.clone(), + reward_addr.clone(), + &fund_msg, + &extra_funding, + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidFunds {}); + + // Cw20 funding fails + let cw20_token = instantiate_cw20( + &mut app, + vec![Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(500000000), + }], + ); + let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); + let fund_msg = Cw20ExecuteMsg::Send { + contract: reward_addr.into_string(), + amount: Uint128::new(100), + msg: fund_sub_msg, + }; + let err: ContractError = app + .borrow_mut() + .execute_contract(owner, cw20_token, &fund_msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidCw20 {}); +} + +#[test] +fn test_cannot_fund_with_wrong_coin_cw20() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let _denom = "utest".to_string(); + let (staking_addr, _cw20_addr) = setup_staking_contract(&mut app, initial_balances); + let reward_token = instantiate_cw20( + &mut app, + vec![Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(500000000), + }], + ); + let reward_addr = setup_reward_contract( + &mut app, + staking_addr, + Denom::Cw20(Addr::unchecked("dummy_cw20")), + admin.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + // Test with invalid token + let fund_sub_msg = to_json_binary(&ReceiveMsg::Fund {}).unwrap(); + let fund_msg = Cw20ExecuteMsg::Send { + contract: reward_addr.clone().into_string(), + amount: Uint128::new(100), + msg: fund_sub_msg, + }; + let err: ContractError = app + .borrow_mut() + .execute_contract(admin.clone(), reward_token, &fund_msg, &[]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidCw20 {}); + + // Test does not work when funded with native + let invalid_funding = vec![coin(100, "invalid")]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: invalid_funding.clone(), + } + })) + .unwrap(); + + let fund_msg = ExecuteMsg::Fund {}; + + let err: ContractError = app + .borrow_mut() + .execute_contract(admin, reward_addr, &fund_msg, &invalid_funding) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidFunds {}) +} + +#[test] +fn test_rewards_with_zero_staked() { + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + // Instantiate cw20 contract + let cw20_addr = instantiate_cw20(&mut app, initial_balances.clone()); + app.update_block(next_block); + // Instantiate staking contract + let staking_addr = instantiate_staking(&mut app, cw20_addr.clone(), None); + app.update_block(next_block); + let reward_funding = vec![coin(100000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let reward_addr = setup_reward_contract( + &mut app, + staking_addr.clone(), + Denom::Native(denom), + admin.clone(), + ); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + let _res = app + .borrow_mut() + .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(1000)); + assert_eq!(res.reward.period_finish, 101000); + assert_eq!(res.reward.reward_duration, 100000); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 0); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 0); + + for coin in initial_balances { + stake_tokens( + &mut app, + &staking_addr, + &cw20_addr, + coin.address, + coin.amount.u128(), + ); + } + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 250); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 250); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 1000); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 500); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 500); +} + +#[test] +fn test_small_rewards() { + // This test was added due to a bug in the contract not properly paying out small reward + // amounts due to floor division + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); + let reward_funding = vec![coin(1000000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let reward_addr = + setup_reward_contract(&mut app, staking_addr, Denom::Native(denom), admin.clone()); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + let _res = app + .borrow_mut() + .execute_contract(admin, reward_addr.clone(), &fund_msg, &reward_funding) + .unwrap(); + + let res: InfoResponse = app + .borrow_mut() + .wrap() + .query_wasm_smart(&reward_addr, &QueryMsg::Info {}) + .unwrap(); + + assert_eq!(res.reward.reward_rate, Uint128::new(10)); + assert_eq!(res.reward.period_finish, 101000); + assert_eq!(res.reward.reward_duration, 100000); + + app.borrow_mut().update_block(next_block); + assert_pending_rewards(&mut app, &reward_addr, ADDR1, 5); + assert_pending_rewards(&mut app, &reward_addr, ADDR2, 2); + assert_pending_rewards(&mut app, &reward_addr, ADDR3, 2); +} + +#[test] +fn test_zero_reward_rate_failed() { + // This test is due to a bug when funder provides rewards config that results in less then 1 + // reward per block which rounds down to zer0 + let mut app = mock_app(); + let admin = Addr::unchecked(OWNER); + app.borrow_mut().update_block(|b| b.height = 0); + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); + let reward_funding = vec![coin(10000, denom.clone())]; + app.sudo(SudoMsg::Bank({ + BankSudo::Mint { + to_address: admin.to_string(), + amount: reward_funding.clone(), + } + })) + .unwrap(); + let reward_addr = + setup_reward_contract(&mut app, staking_addr, Denom::Native(denom), admin.clone()); + + app.borrow_mut().update_block(|b| b.height = 1000); + + let fund_msg = ExecuteMsg::Fund {}; + + let _res = app + .borrow_mut() + .execute_contract(admin, reward_addr, &fund_msg, &reward_funding) + .unwrap_err(); +} + +#[test] +fn test_migrate_from_v1() { + let mut app = App::default(); + + let v1_code = app.store_code(cw20_stake_external_rewards_v1_contract()); + let v2_code = app.store_code(cw20_stake_external_rewards_contract()); + + let initial_balances = vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::new(100), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::new(50), + }, + Cw20Coin { + address: ADDR3.to_string(), + amount: Uint128::new(50), + }, + ]; + let denom = "utest".to_string(); + let (staking_addr, _) = setup_staking_contract(&mut app, initial_balances); + + let rewards_addr = app + .instantiate_contract( + v1_code, + Addr::unchecked(OWNER), + &v1::msg::InstantiateMsg { + owner: Some(OWNER.to_string()), + manager: Some(ADDR1.to_string()), + staking_contract: staking_addr.into_string(), + reward_token: cw20_013::Denom::Native(denom), + reward_duration: 10000, + }, + &[], + "rewards".to_string(), + Some(OWNER.to_string()), + ) + .unwrap(); + + app.execute( + Addr::unchecked(OWNER), + WasmMsg::Migrate { + contract_addr: rewards_addr.to_string(), + new_code_id: v2_code, + msg: to_json_binary(&MigrateMsg::FromV1 {}).unwrap(), + } + .into(), + ) + .unwrap(); + + let ownership = get_ownership(&app, &rewards_addr); + assert_eq!( + ownership, + Ownership:: { + owner: Some(Addr::unchecked(OWNER)), + pending_owner: None, + pending_expiry: None, + } + ); + + let err: ContractError = app + .execute( + Addr::unchecked(OWNER), + WasmMsg::Migrate { + contract_addr: rewards_addr.to_string(), + new_code_id: v2_code, + msg: to_json_binary(&MigrateMsg::FromV1 {}).unwrap(), + } + .into(), + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::AlreadyMigrated {}); +} diff --git a/contracts/staking/cw20-stake-reward-distributor/Cargo.toml b/contracts/staking/cw20-stake-reward-distributor/Cargo.toml index 75972d965..887dea77d 100644 --- a/contracts/staking/cw20-stake-reward-distributor/Cargo.toml +++ b/contracts/staking/cw20-stake-reward-distributor/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "cw20-stake-reward-distributor" edition = "2018" -authors = ["Vernon Johnson , ekez "] +authors = [ + "Vernon Johnson , ekez ", +] description = "Distributes cw20 staking rewards." license = { workspace = true } repository = { workspace = true } @@ -24,11 +26,12 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } cw20 = { workspace = true } cw-utils = { workspace = true } -cw20-base = { workspace = true, features = ["library"] } -cw20-stake = { workspace = true, features = ["library"]} +cw20-base = { workspace = true, features = ["library"] } +cw20-stake = { workspace = true, features = ["library"] } thiserror = { workspace = true } cw-ownable = { workspace = true } cw20-stake-reward-distributor-v1 = { workspace = true, features = ["library"] } [dev-dependencies] cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/staking/cw20-stake-reward-distributor/src/tests.rs b/contracts/staking/cw20-stake-reward-distributor/src/tests.rs index 7b6bde529..552491b96 100644 --- a/contracts/staking/cw20-stake-reward-distributor/src/tests.rs +++ b/contracts/staking/cw20-stake-reward-distributor/src/tests.rs @@ -1,58 +1,24 @@ +use cosmwasm_std::{to_json_binary, Addr, Uint128, WasmMsg}; +use cw20::Cw20Coin; +use cw20_stake_reward_distributor_v1 as v1; +use cw_multi_test::{next_block, App, Executor}; +use cw_ownable::{Action, Expiration, Ownership, OwnershipError}; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, cw20_stake_external_rewards_contract, + v1::cw20_stake_external_rewards_v1_contract, +}; + use crate::{ msg::{ExecuteMsg, InfoResponse, InstantiateMsg, MigrateMsg, QueryMsg}, state::Config, ContractError, }; -use cw20_stake_reward_distributor_v1 as v1; - -use cosmwasm_std::{to_json_binary, Addr, Empty, Uint128, WasmMsg}; -use cw20::Cw20Coin; -use cw_multi_test::{next_block, App, Contract, ContractWrapper, Executor}; -use cw_ownable::{Action, Expiration, Ownership, OwnershipError}; - const OWNER: &str = "owner"; const OWNER2: &str = "owner2"; -pub fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn staking_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - -fn distributor_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -fn distributor_contract_v1() -> Box> { - let contract = ContractWrapper::new( - v1::contract::execute, - v1::contract::instantiate, - v1::contract::query, - ); - Box::new(contract) -} - fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { - let cw20_id = app.store_code(cw20_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let msg = cw20_base::msg::InstantiateMsg { name: String::from("Test"), symbol: String::from("TEST"), @@ -67,7 +33,7 @@ fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { } fn instantiate_staking(app: &mut App, cw20_addr: Addr) -> Addr { - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(cw20_stake_contract()); let msg = cw20_stake::msg::InstantiateMsg { owner: Some(OWNER.to_string()), token_address: cw20_addr.to_string(), @@ -85,7 +51,7 @@ fn instantiate_staking(app: &mut App, cw20_addr: Addr) -> Addr { } fn instantiate_distributor(app: &mut App, msg: InstantiateMsg) -> Addr { - let code_id = app.store_code(distributor_contract()); + let code_id = app.store_code(cw20_stake_external_rewards_contract()); app.instantiate_contract( code_id, Addr::unchecked(OWNER), @@ -351,7 +317,7 @@ fn test_instantiate_invalid_addrs() { reward_token: "invalid_cw20".to_string(), }; - let code_id = app.store_code(distributor_contract()); + let code_id = app.store_code(cw20_stake_external_rewards_contract()); let err: ContractError = app .instantiate_contract( code_id, @@ -689,8 +655,8 @@ fn test_migrate_from_v1() { ); let staking_addr = instantiate_staking(&mut app, cw20_addr.clone()); - let v1_code = app.store_code(distributor_contract_v1()); - let v2_code = app.store_code(distributor_contract()); + let v1_code = app.store_code(cw20_stake_external_rewards_v1_contract()); + let v2_code = app.store_code(cw20_stake_external_rewards_contract()); let distributor = app .instantiate_contract( v1_code, diff --git a/contracts/staking/cw20-stake/Cargo.toml b/contracts/staking/cw20-stake/Cargo.toml index 4417b372b..5804da3e3 100644 --- a/contracts/staking/cw20-stake/Cargo.toml +++ b/contracts/staking/cw20-stake/Cargo.toml @@ -37,3 +37,4 @@ cw-utils-v1 = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } anyhow = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/staking/cw20-stake/src/tests.rs b/contracts/staking/cw20-stake/src/tests.rs index 147bd806f..4dc6b7fcd 100644 --- a/contracts/staking/cw20-stake/src/tests.rs +++ b/contracts/staking/cw20-stake/src/tests.rs @@ -1,12 +1,13 @@ use anyhow::Result as AnyResult; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{to_json_binary, Addr, Empty, MessageInfo, Uint128, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, MessageInfo, Uint128, WasmMsg}; use cw20::Cw20Coin; use cw_controllers::{Claim, ClaimsResponse}; -use cw_multi_test::{next_block, App, AppResponse, Contract, ContractWrapper, Executor}; +use cw_multi_test::{next_block, App, AppResponse, Executor}; use cw_ownable::{Action, Ownership, OwnershipError}; use cw_utils::Duration; use cw_utils::Expiration::AtHeight; +use dao_testing::contracts::{cw20_base_contract, cw20_stake_contract, v1::cw20_stake_v1_contract}; use dao_voting::duration::UnstakingDurationError; use std::borrow::BorrowMut; @@ -26,35 +27,6 @@ const ADDR3: &str = "addr0003"; const ADDR4: &str = "addr0004"; const OWNER: &str = "owner"; -fn contract_staking() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - -fn contract_staking_v1() -> Box> { - let contract = ContractWrapper::new( - v1::contract::execute, - v1::contract::instantiate, - v1::contract::query, - ) - .with_migrate(v1::contract::migrate); - Box::new(contract) -} - -fn contract_cw20() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn mock_app() -> App { App::default() } @@ -72,7 +44,7 @@ fn get_balance, U: Into>( } fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { - let cw20_id = app.store_code(contract_cw20()); + let cw20_id = app.store_code(cw20_base_contract()); let msg = cw20_base::msg::InstantiateMsg { name: String::from("Test"), symbol: String::from("TEST"), @@ -87,7 +59,7 @@ fn instantiate_cw20(app: &mut App, initial_balances: Vec) -> Addr { } fn instantiate_staking(app: &mut App, cw20: Addr, unstaking_duration: Option) -> Addr { - let staking_code_id = app.store_code(contract_staking()); + let staking_code_id = app.store_code(cw20_stake_contract()); let msg = crate::msg::InstantiateMsg { owner: Some(OWNER.to_string()), token_address: cw20.to_string(), @@ -1127,8 +1099,8 @@ fn test_migrate_from_v1() { }], ); - let v1_code = app.store_code(contract_staking_v1()); - let v2_code = app.store_code(contract_staking()); + let v1_code = app.store_code(cw20_stake_v1_contract()); + let v2_code = app.store_code(cw20_stake_contract()); let staking = app .instantiate_contract( diff --git a/contracts/test/dao-proposal-hook-counter/Cargo.toml b/contracts/test/dao-proposal-hook-counter/Cargo.toml index 395fb338a..9ac82759a 100644 --- a/contracts/test/dao-proposal-hook-counter/Cargo.toml +++ b/contracts/test/dao-proposal-hook-counter/Cargo.toml @@ -35,3 +35,4 @@ dao-interface = { workspace = true } dao-dao-core = { workspace = true } dao-proposal-single = { workspace = true } cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/test/dao-proposal-hook-counter/src/tests.rs b/contracts/test/dao-proposal-hook-counter/src/tests.rs index 611c22dad..e28ed1b34 100644 --- a/contracts/test/dao-proposal-hook-counter/src/tests.rs +++ b/contracts/test/dao-proposal-hook-counter/src/tests.rs @@ -1,10 +1,13 @@ -use cosmwasm_std::{to_json_binary, Addr, Empty, Uint128}; +use cosmwasm_std::{to_json_binary, Addr, Uint128}; use cw20::Cw20Coin; use cw_hooks::HooksResponse; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, Executor}; use dao_interface::state::ProposalModule; use dao_interface::state::{Admin, ModuleInstantiateInfo}; - +use dao_testing::contracts::{ + cw20_base_contract, dao_dao_core_contract, dao_proposal_hook_counter_contract, + dao_proposal_single_contract, dao_voting_cw20_balance_contract, +}; use dao_voting::{ pre_propose::PreProposeInfo, threshold::{PercentageThreshold, Threshold}, @@ -17,54 +20,6 @@ use dao_voting::proposal::SingleChoiceProposeMsg as ProposeMsg; const CREATOR_ADDR: &str = "creator"; -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn single_govmod_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_single::contract::execute, - dao_proposal_single::contract::instantiate, - dao_proposal_single::contract::query, - ) - .with_reply(dao_proposal_single::contract::reply); - Box::new(contract) -} - -fn cw20_balances_voting() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_balance::contract::execute, - dao_voting_cw20_balance::contract::instantiate, - dao_voting_cw20_balance::contract::query, - ) - .with_reply(dao_voting_cw20_balance::contract::reply); - Box::new(contract) -} - -fn cw_gov_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply); - Box::new(contract) -} - -fn counters_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) -} - fn instantiate_governance( app: &mut App, code_id: u64, @@ -87,9 +42,9 @@ fn instantiate_with_default_governance( msg: dao_proposal_single::msg::InstantiateMsg, initial_balances: Option>, ) -> Addr { - let cw20_id = app.store_code(cw20_contract()); - let governance_id = app.store_code(cw_gov_contract()); - let votemod_id = app.store_code(cw20_balances_voting()); + let cw20_id = app.store_code(cw20_base_contract()); + let governance_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_balance_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -140,8 +95,8 @@ fn instantiate_with_default_governance( #[test] fn test_counters() { let mut app = App::default(); - let govmod_id = app.store_code(single_govmod_contract()); - let counters_id = app.store_code(counters_contract()); + let govmod_id = app.store_code(dao_proposal_single_contract()); + let counters_id = app.store_code(dao_proposal_hook_counter_contract()); let threshold = Threshold::AbsolutePercentage { percentage: PercentageThreshold::Majority {}, diff --git a/contracts/test/dao-voting-cw20-balance/Cargo.toml b/contracts/test/dao-voting-cw20-balance/Cargo.toml index f126b6840..94d1f0cb0 100644 --- a/contracts/test/dao-voting-cw20-balance/Cargo.toml +++ b/contracts/test/dao-voting-cw20-balance/Cargo.toml @@ -26,7 +26,8 @@ cw-utils = { workspace = true } thiserror = { workspace = true } dao-dao-macros = { workspace = true } dao-interface = { workspace = true } -cw20-base = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } [dev-dependencies] cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/test/dao-voting-cw20-balance/src/tests.rs b/contracts/test/dao-voting-cw20-balance/src/tests.rs index 4560fd5ea..79d1a6cd4 100644 --- a/contracts/test/dao-voting-cw20-balance/src/tests.rs +++ b/contracts/test/dao-voting-cw20-balance/src/tests.rs @@ -1,33 +1,15 @@ -use cosmwasm_std::{Addr, Empty, Uint128}; +use cosmwasm_std::{Addr, Uint128}; use cw2::ContractVersion; use cw20::{Cw20Coin, MinterResponse, TokenInfoResponse}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, Executor}; use dao_interface::voting::{InfoResponse, VotingPowerAtHeightResponse}; +use dao_testing::contracts::{cw20_base_contract, dao_voting_cw20_balance_contract}; use crate::msg::{InstantiateMsg, QueryMsg}; const DAO_ADDR: &str = "dao"; const CREATOR_ADDR: &str = "creator"; -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn balance_voting_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - fn instantiate_voting(app: &mut App, voting_id: u64, msg: InstantiateMsg) -> Addr { app.instantiate_contract( voting_id, @@ -44,8 +26,8 @@ fn instantiate_voting(app: &mut App, voting_id: u64, msg: InstantiateMsg) -> Add #[should_panic(expected = "Initial governance token balances must not be empty")] fn test_instantiate_zero_supply() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(balance_voting_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); instantiate_voting( &mut app, voting_id, @@ -70,8 +52,8 @@ fn test_instantiate_zero_supply() { #[should_panic(expected = "Initial governance token balances must not be empty")] fn test_instantiate_no_balances() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(balance_voting_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); instantiate_voting( &mut app, voting_id, @@ -92,8 +74,8 @@ fn test_instantiate_no_balances() { #[test] fn test_contract_info() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(balance_voting_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); let voting_addr = instantiate_voting( &mut app, @@ -132,8 +114,8 @@ fn test_contract_info() { #[test] fn test_new_cw20() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(balance_voting_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); let voting_addr = instantiate_voting( &mut app, @@ -257,8 +239,8 @@ fn test_new_cw20() { #[test] fn test_existing_cw20() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(balance_voting_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_balance_contract()); let token_addr = app .instantiate_contract( diff --git a/contracts/voting/dao-voting-cw20-staked/Cargo.toml b/contracts/voting/dao-voting-cw20-staked/Cargo.toml index 4eae84a64..8a3857f54 100644 --- a/contracts/voting/dao-voting-cw20-staked/Cargo.toml +++ b/contracts/voting/dao-voting-cw20-staked/Cargo.toml @@ -32,3 +32,4 @@ dao-voting = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/voting/dao-voting-cw20-staked/src/tests.rs b/contracts/voting/dao-voting-cw20-staked/src/tests.rs index 0022f98ed..1ba100fb0 100644 --- a/contracts/voting/dao-voting-cw20-staked/src/tests.rs +++ b/contracts/voting/dao-voting-cw20-staked/src/tests.rs @@ -1,11 +1,14 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, CosmosMsg, Decimal, Empty, Uint128, WasmMsg, + to_json_binary, Addr, CosmosMsg, Decimal, Uint128, WasmMsg, }; use cw2::ContractVersion; use cw20::{BalanceResponse, Cw20Coin, MinterResponse, TokenInfoResponse}; -use cw_multi_test::{next_block, App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{next_block, App, Executor}; use dao_interface::voting::{InfoResponse, IsActiveResponse, VotingPowerAtHeightResponse}; +use dao_testing::contracts::{ + cw20_base_contract, cw20_stake_contract, dao_voting_cw20_staked_contract, +}; use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; use crate::{ @@ -16,35 +19,6 @@ use crate::{ const DAO_ADDR: &str = "dao"; const CREATOR_ADDR: &str = "creator"; -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn staking_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - -fn staked_balance_voting_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - fn instantiate_voting(app: &mut App, voting_id: u64, msg: InstantiateMsg) -> Addr { app.instantiate_contract( voting_id, @@ -71,9 +45,9 @@ fn stake_tokens(app: &mut App, staking_addr: Addr, cw20_addr: Addr, sender: &str #[should_panic(expected = "Initial governance token balances must not be empty")] fn test_instantiate_zero_supply() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, voting_id, @@ -102,9 +76,9 @@ fn test_instantiate_zero_supply() { #[should_panic(expected = "Initial governance token balances must not be empty")] fn test_instantiate_no_balances() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, voting_id, @@ -130,9 +104,9 @@ fn test_instantiate_no_balances() { #[should_panic(expected = "Active threshold count must be greater than zero")] fn test_instantiate_zero_active_threshold_count() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, voting_id, @@ -162,9 +136,9 @@ fn test_instantiate_zero_active_threshold_count() { #[test] fn test_contract_info() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -213,9 +187,9 @@ fn test_contract_info() { #[test] fn test_new_cw20() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -374,9 +348,9 @@ fn test_new_cw20() { #[test] fn test_existing_cw20_new_staking() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_id = app.store_code(cw20_stake_contract()); let token_addr = app .instantiate_contract( @@ -525,9 +499,9 @@ fn test_existing_cw20_new_staking() { #[test] fn test_existing_cw20_existing_staking() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_id = app.store_code(cw20_stake_contract()); let token_addr = app .instantiate_contract( @@ -726,9 +700,9 @@ fn test_existing_cw20_existing_staking() { #[test] fn test_different_heights() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_id = app.store_code(cw20_stake_contract()); let token_addr = app .instantiate_contract( @@ -926,9 +900,9 @@ fn test_different_heights() { #[test] fn test_active_threshold_absolute_count() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -986,9 +960,9 @@ fn test_active_threshold_absolute_count() { #[test] fn test_active_threshold_percent() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -1046,9 +1020,9 @@ fn test_active_threshold_percent() { #[test] fn test_active_threshold_percent_rounds_up() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -1121,9 +1095,9 @@ fn test_active_threshold_percent_rounds_up() { #[test] fn test_active_threshold_none() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -1159,9 +1133,9 @@ fn test_active_threshold_none() { #[test] fn test_update_active_threshold() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = instantiate_voting( &mut app, @@ -1227,9 +1201,9 @@ fn test_update_active_threshold() { #[should_panic(expected = "Active threshold percentage must be greater than 0 and less than 1")] fn test_active_threshold_percentage_gt_100() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, @@ -1261,9 +1235,9 @@ fn test_active_threshold_percentage_gt_100() { #[should_panic(expected = "Active threshold percentage must be greater than 0 and less than 1")] fn test_active_threshold_percentage_lte_0() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, @@ -1295,9 +1269,9 @@ fn test_active_threshold_percentage_lte_0() { #[should_panic(expected = "Absolute count threshold cannot be greater than the total token supply")] fn test_active_threshold_absolute_count_invalid() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); instantiate_voting( &mut app, @@ -1328,9 +1302,9 @@ fn test_active_threshold_absolute_count_invalid() { #[test] fn test_migrate() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); - let voting_id = app.store_code(staked_balance_voting_contract()); - let staking_contract_id = app.store_code(staking_contract()); + let cw20_id = app.store_code(cw20_base_contract()); + let voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let staking_contract_id = app.store_code(cw20_stake_contract()); let voting_addr = app .instantiate_contract( diff --git a/contracts/voting/dao-voting-cw4/Cargo.toml b/contracts/voting/dao-voting-cw4/Cargo.toml index 55c671560..bc68a9fd9 100644 --- a/contracts/voting/dao-voting-cw4/Cargo.toml +++ b/contracts/voting/dao-voting-cw4/Cargo.toml @@ -30,3 +30,4 @@ cw4-group = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/contracts/voting/dao-voting-cw4/src/tests.rs b/contracts/voting/dao-voting-cw4/src/tests.rs index 769c53c4c..019295995 100644 --- a/contracts/voting/dao-voting-cw4/src/tests.rs +++ b/contracts/voting/dao-voting-cw4/src/tests.rs @@ -1,12 +1,13 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, CosmosMsg, Empty, Uint128, WasmMsg, + to_json_binary, Addr, CosmosMsg, Uint128, WasmMsg, }; use cw2::ContractVersion; -use cw_multi_test::{next_block, App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{next_block, App, Executor}; use dao_interface::voting::{ InfoResponse, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse, }; +use dao_testing::contracts::{cw4_group_contract, dao_voting_cw4_contract}; use crate::{ contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, @@ -20,26 +21,6 @@ const ADDR2: &str = "addr2"; const ADDR3: &str = "addr3"; const ADDR4: &str = "addr4"; -fn cw4_contract() -> Box> { - let contract = ContractWrapper::new( - cw4_group::contract::execute, - cw4_group::contract::instantiate, - cw4_group::contract::query, - ); - Box::new(contract) -} - -fn voting_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - fn instantiate_voting(app: &mut App, voting_id: u64, msg: InstantiateMsg) -> Addr { app.instantiate_contract( voting_id, @@ -53,8 +34,8 @@ fn instantiate_voting(app: &mut App, voting_id: u64, msg: InstantiateMsg) -> Add } fn setup_test_case(app: &mut App) -> Addr { - let cw4_id = app.store_code(cw4_contract()); - let voting_id = app.store_code(voting_contract()); + let cw4_id = app.store_code(cw4_group_contract()); + let voting_id = app.store_code(dao_voting_cw4_contract()); let members = vec![ cw4::Member { @@ -93,8 +74,8 @@ fn test_instantiate() { let _voting_addr = setup_test_case(&mut app); // Instantiate with no members, error - let voting_id = app.store_code(voting_contract()); - let cw4_id = app.store_code(cw4_contract()); + let voting_id = app.store_code(dao_voting_cw4_contract()); + let cw4_id = app.store_code(cw4_group_contract()); let msg = InstantiateMsg { group_contract: GroupContract::New { cw4_group_code_id: cw4_id, @@ -148,8 +129,8 @@ fn test_instantiate() { pub fn test_instantiate_existing_contract() { let mut app = App::default(); - let voting_id = app.store_code(voting_contract()); - let cw4_id = app.store_code(cw4_contract()); + let voting_id = app.store_code(dao_voting_cw4_contract()); + let cw4_id = app.store_code(cw4_group_contract()); // Fail with no members. let cw4_addr = app @@ -573,8 +554,8 @@ fn test_migrate() { ]; // Instantiate with no members, error - let voting_id = app.store_code(voting_contract()); - let cw4_id = app.store_code(cw4_contract()); + let voting_id = app.store_code(dao_voting_cw4_contract()); + let cw4_id = app.store_code(cw4_group_contract()); let msg = InstantiateMsg { group_contract: GroupContract::New { cw4_group_code_id: cw4_id, @@ -631,8 +612,8 @@ fn test_migrate() { fn test_duplicate_member() { let mut app = App::default(); let _voting_addr = setup_test_case(&mut app); - let voting_id = app.store_code(voting_contract()); - let cw4_id = app.store_code(cw4_contract()); + let voting_id = app.store_code(dao_voting_cw4_contract()); + let cw4_id = app.store_code(cw4_group_contract()); // Instantiate with members but have a duplicate // Total weight is actually 69 but ADDR3 appears twice. let msg = InstantiateMsg { diff --git a/contracts/voting/dao-voting-cw721-staked/src/testing/mod.rs b/contracts/voting/dao-voting-cw721-staked/src/testing/mod.rs index c454212c4..aaeeaf8d7 100644 --- a/contracts/voting/dao-voting-cw721-staked/src/testing/mod.rs +++ b/contracts/voting/dao-voting-cw721-staked/src/testing/mod.rs @@ -18,7 +18,7 @@ mod test_tube_env; use cosmwasm_std::Addr; use cw_multi_test::{App, Executor}; use cw_utils::Duration; -use dao_testing::contracts::cw721_staked_voting_contract; +use dao_testing::contracts::dao_voting_cw721_staked_contract; use crate::msg::{InstantiateMsg, NftContract}; @@ -35,7 +35,7 @@ pub(crate) struct CommonTest { pub(crate) fn setup_test(unstaking_duration: Option) -> CommonTest { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let nft = instantiate_cw721_base(&mut app, CREATOR_ADDR, CREATOR_ADDR); let module = app diff --git a/contracts/voting/dao-voting-cw721-staked/src/testing/tests.rs b/contracts/voting/dao-voting-cw721-staked/src/testing/tests.rs index 7126bd904..1ce42119d 100644 --- a/contracts/voting/dao-voting-cw721-staked/src/testing/tests.rs +++ b/contracts/voting/dao-voting-cw721-staked/src/testing/tests.rs @@ -6,7 +6,7 @@ use cw_multi_test::{next_block, App, BankSudo, Executor, SudoMsg}; use cw_utils::Duration; use dao_interface::voting::IsActiveResponse; use dao_testing::contracts::{ - cw721_base_contract, cw721_staked_voting_contract, dao_test_custom_factory, + cw721_base_contract, dao_test_custom_factory_contract, dao_voting_cw721_staked_contract, }; use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; @@ -34,7 +34,7 @@ use super::{ #[test] fn test_instantiate_with_new_cw721_collection() -> anyhow::Result<()> { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); let module_addr = app @@ -421,7 +421,7 @@ fn test_add_remove_hooks() -> anyhow::Result<()> { #[test] fn test_instantiate_with_invalid_duration_fails() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); let err = app @@ -462,7 +462,7 @@ fn test_instantiate_with_invalid_duration_fails() { fn test_instantiate_zero_active_threshold_count() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); app.instantiate_contract( module_id, @@ -502,7 +502,7 @@ fn test_instantiate_zero_active_threshold_count() { fn test_instantiate_invalid_active_threshold_count_new_nft() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); app.instantiate_contract( module_id, @@ -541,7 +541,7 @@ fn test_instantiate_invalid_active_threshold_count_new_nft() { #[should_panic(expected = "Absolute count threshold cannot be greater than the total token supply")] fn test_instantiate_invalid_active_threshold_count_existing_nft() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_addr = instantiate_cw721_base(&mut app, CREATOR_ADDR, CREATOR_ADDR); app.instantiate_contract( @@ -567,7 +567,7 @@ fn test_instantiate_invalid_active_threshold_count_existing_nft() { fn test_active_threshold_absolute_count() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let voting_addr = app .instantiate_contract( @@ -647,7 +647,7 @@ fn test_active_threshold_absolute_count() { fn test_active_threshold_percent() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let voting_addr = app .instantiate_contract( @@ -708,7 +708,7 @@ fn test_active_threshold_percent() { fn test_active_threshold_percent_rounds_up() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let voting_addr = app .instantiate_contract( @@ -810,7 +810,7 @@ fn test_active_threshold_percent_rounds_up() { fn test_update_active_threshold() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let voting_addr = app .instantiate_contract( @@ -887,7 +887,7 @@ fn test_update_active_threshold() { fn test_active_threshold_percentage_gt_100() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); app.instantiate_contract( module_id, @@ -929,7 +929,7 @@ fn test_active_threshold_percentage_gt_100() { fn test_active_threshold_percentage_lte_0() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); app.instantiate_contract( module_id, @@ -967,7 +967,7 @@ fn test_active_threshold_percentage_lte_0() { #[test] fn test_invalid_instantiate_msg() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); let err = app @@ -1006,7 +1006,7 @@ fn test_invalid_instantiate_msg() { #[test] fn test_invalid_initial_nft_msg() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); let err = app @@ -1045,7 +1045,7 @@ fn test_invalid_initial_nft_msg() { #[test] fn test_invalid_initial_nft_msg_wrong_absolute_count() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); let err = app @@ -1096,7 +1096,7 @@ fn test_invalid_initial_nft_msg_wrong_absolute_count() { fn test_no_initial_nfts_fails() { let mut app = App::default(); let cw721_id = app.store_code(cw721_base_contract()); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let err = app .instantiate_contract( @@ -1133,9 +1133,9 @@ fn test_no_initial_nfts_fails() { #[test] fn test_factory() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); - let factory_id = app.store_code(dao_test_custom_factory()); + let factory_id = app.store_code(dao_test_custom_factory_contract()); // Instantiate factory let factory_addr = app @@ -1186,9 +1186,9 @@ fn test_factory() { #[test] fn test_factory_with_funds_pass_through() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); - let factory_id = app.store_code(dao_test_custom_factory()); + let factory_id = app.store_code(dao_test_custom_factory_contract()); // Mint some tokens to creator app.sudo(SudoMsg::Bank(BankSudo::Mint { @@ -1307,7 +1307,7 @@ fn test_factory_with_funds_pass_through() { #[should_panic(expected = "Factory message must serialize to WasmMsg::Execute")] fn test_unsupported_factory_msg() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let cw721_id = app.store_code(cw721_base_contract()); // Instantiate using factory succeeds @@ -1352,9 +1352,9 @@ fn test_unsupported_factory_msg() { )] fn test_factory_wrong_callback() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let _cw721_id = app.store_code(cw721_base_contract()); - let factory_id = app.store_code(dao_test_custom_factory()); + let factory_id = app.store_code(dao_test_custom_factory_contract()); // Instantiate factory let factory_addr = app @@ -1400,9 +1400,9 @@ fn test_factory_wrong_callback() { #[should_panic(expected = "Invalid reply from sub-message: Missing reply data")] fn test_factory_no_callback() { let mut app = App::default(); - let module_id = app.store_code(cw721_staked_voting_contract()); + let module_id = app.store_code(dao_voting_cw721_staked_contract()); let _cw721_id = app.store_code(cw721_base_contract()); - let factory_id = app.store_code(dao_test_custom_factory()); + let factory_id = app.store_code(dao_test_custom_factory_contract()); // Instantiate factory let factory_addr = app diff --git a/contracts/voting/dao-voting-onft-staked/src/testing/mod.rs b/contracts/voting/dao-voting-onft-staked/src/testing/mod.rs index 487a4dde0..30012f8fa 100644 --- a/contracts/voting/dao-voting-onft-staked/src/testing/mod.rs +++ b/contracts/voting/dao-voting-onft-staked/src/testing/mod.rs @@ -9,7 +9,7 @@ use app::OmniflixApp; use cosmwasm_std::Addr; use cw_multi_test::Executor; use cw_utils::Duration; -use dao_testing::contracts::onft_staked_voting_contract; +use dao_testing::contracts::dao_voting_onft_staked_contract; use dao_voting::threshold::ActiveThreshold; use crate::msg::{InstantiateMsg, OnftCollection}; @@ -33,7 +33,7 @@ pub(crate) fn setup_test( active_threshold: Option, ) -> CommonTest { let mut app = OmniflixApp::new(); - let module_id = app.store_code(onft_staked_voting_contract()); + let module_id = app.store_code(dao_voting_onft_staked_contract()); let nft = create_onft_collection(&mut app, "nft", DAO, DAO); let module = app diff --git a/contracts/voting/dao-voting-token-staked/src/tests/multitest/tests.rs b/contracts/voting/dao-voting-token-staked/src/tests/multitest/tests.rs index 90b4fab28..31133e300 100644 --- a/contracts/voting/dao-voting-token-staked/src/tests/multitest/tests.rs +++ b/contracts/voting/dao-voting-token-staked/src/tests/multitest/tests.rs @@ -5,16 +5,17 @@ use crate::msg::{ }; use crate::state::Config; use cosmwasm_std::testing::{mock_dependencies, mock_env}; -use cosmwasm_std::{coins, Addr, Coin, Decimal, Empty, Uint128}; +use cosmwasm_std::{coins, Addr, Coin, Decimal, Uint128}; use cw_controllers::ClaimsResponse; -use cw_multi_test::{ - next_block, App, AppResponse, BankSudo, Contract, ContractWrapper, Executor, SudoMsg, -}; +use cw_multi_test::{next_block, App, AppResponse, BankSudo, Executor, SudoMsg}; use cw_utils::Duration; use dao_interface::voting::{ DenomResponse, InfoResponse, IsActiveResponse, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse, }; +use dao_testing::contracts::{ + dao_proposal_hook_counter_contract, dao_voting_token_staked_contract, +}; use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; const DAO_ADDR: &str = "dao"; @@ -24,26 +25,6 @@ const DENOM: &str = "ujuno"; const INVALID_DENOM: &str = "uinvalid"; const ODD_DENOM: &str = "uodd"; -fn hook_counter_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_hook_counter::contract::execute, - dao_proposal_hook_counter::contract::instantiate, - dao_proposal_hook_counter::contract::query, - ); - Box::new(contract) -} - -fn staking_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply) - .with_migrate(crate::contract::migrate); - Box::new(contract) -} - fn mock_app() -> App { let mut app = App::default(); app.sudo(SudoMsg::Bank(BankSudo::Mint { @@ -205,7 +186,7 @@ fn get_balance(app: &mut App, address: &str, denom: &str) -> Uint128 { fn test_instantiate_existing() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); // Populated fields instantiate_staking( &mut app, @@ -249,7 +230,7 @@ fn test_instantiate_existing() { fn test_instantiate_invalid_unstaking_duration_height() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); // Populated fields instantiate_staking( @@ -272,7 +253,7 @@ fn test_instantiate_invalid_unstaking_duration_height() { fn test_instantiate_invalid_unstaking_duration_time() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); // Populated fields with height instantiate_staking( @@ -295,7 +276,7 @@ fn test_instantiate_invalid_unstaking_duration_time() { fn test_stake_invalid_denom() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -316,7 +297,7 @@ fn test_stake_invalid_denom() { fn test_stake_valid_denom() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -339,7 +320,7 @@ fn test_stake_valid_denom() { fn test_unstake_none_staked() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -360,7 +341,7 @@ fn test_unstake_none_staked() { fn test_unstake_zero_tokens() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -381,7 +362,7 @@ fn test_unstake_zero_tokens() { fn test_unstake_invalid_balance() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -406,7 +387,7 @@ fn test_unstake_invalid_balance() { fn test_unstake() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -443,7 +424,7 @@ fn test_unstake() { fn test_unstake_no_unstaking_duration() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -482,7 +463,7 @@ fn test_unstake_no_unstaking_duration() { fn test_claim_no_claims() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -503,7 +484,7 @@ fn test_claim_no_claims() { fn test_claim_claim_not_reached() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -532,7 +513,7 @@ fn test_claim_claim_not_reached() { fn test_claim() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -585,7 +566,7 @@ fn test_claim() { fn test_update_config_invalid_sender() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -606,7 +587,7 @@ fn test_update_config_invalid_sender() { fn test_update_config_as_owner() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -636,7 +617,7 @@ fn test_update_config_as_owner() { fn test_update_config_invalid_duration() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -657,7 +638,7 @@ fn test_update_config_invalid_duration() { fn test_query_dao() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -679,7 +660,7 @@ fn test_query_dao() { fn test_query_info() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -701,7 +682,7 @@ fn test_query_info() { fn test_query_claims() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -739,7 +720,7 @@ fn test_query_claims() { fn test_query_get_config() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -765,7 +746,7 @@ fn test_query_get_config() { fn test_voting_power_queries() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -873,7 +854,7 @@ fn test_voting_power_queries() { fn test_query_list_stakers() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -960,7 +941,7 @@ fn test_query_list_stakers() { fn test_instantiate_zero_active_threshold_count() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); instantiate_staking( &mut app, staking_id, @@ -980,7 +961,7 @@ fn test_instantiate_zero_active_threshold_count() { fn test_active_threshold_absolute_count() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, @@ -1019,7 +1000,7 @@ fn test_active_threshold_absolute_count() { fn test_active_threshold_percent() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -1057,7 +1038,7 @@ fn test_active_threshold_percent() { fn test_active_threshold_percent_rounds_up() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -1104,7 +1085,7 @@ fn test_active_threshold_percent_rounds_up() { fn test_active_threshold_none() { let mut app = App::default(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -1129,7 +1110,7 @@ fn test_active_threshold_none() { fn test_update_active_threshold() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, staking_id, @@ -1181,7 +1162,7 @@ fn test_update_active_threshold() { fn test_active_threshold_percentage_gt_100() { let mut app = App::default(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); instantiate_staking( &mut app, staking_id, @@ -1204,7 +1185,7 @@ fn test_active_threshold_percentage_gt_100() { fn test_active_threshold_percentage_lte_0() { let mut app = App::default(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); instantiate_staking( &mut app, staking_id, @@ -1225,7 +1206,7 @@ fn test_active_threshold_percentage_lte_0() { fn test_active_threshold_absolute_count_invalid() { let mut app = App::default(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); instantiate_staking( &mut app, staking_id, @@ -1245,7 +1226,7 @@ fn test_active_threshold_absolute_count_invalid() { fn test_add_remove_hooks() { let mut app = App::default(); - let staking_id = app.store_code(staking_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); let addr = instantiate_staking( &mut app, @@ -1307,8 +1288,8 @@ fn test_add_remove_hooks() { fn test_staking_hooks() { let mut app = mock_app(); - let staking_id = app.store_code(staking_contract()); - let hook_id = app.store_code(hook_counter_contract()); + let staking_id = app.store_code(dao_voting_token_staked_contract()); + let hook_id = app.store_code(dao_proposal_hook_counter_contract()); let hook = app .instantiate_contract( diff --git a/packages/cw-denom/Cargo.toml b/packages/cw-denom/Cargo.toml index dfb3b543d..8a0589efc 100644 --- a/packages/cw-denom/Cargo.toml +++ b/packages/cw-denom/Cargo.toml @@ -17,3 +17,4 @@ cw20 = { workspace = true } [dev-dependencies] cw20-base = { workspace = true } cw-multi-test = { workspace = true } +dao-testing = { workspace = true } diff --git a/packages/cw-denom/src/integration_tests.rs b/packages/cw-denom/src/integration_tests.rs index 0cf73c55a..70dba3120 100644 --- a/packages/cw-denom/src/integration_tests.rs +++ b/packages/cw-denom/src/integration_tests.rs @@ -1,23 +1,15 @@ -use cosmwasm_std::{coins, Addr, Empty, Uint128}; +use cosmwasm_std::{coins, Addr, Uint128}; use cw20::Cw20Coin; -use cw_multi_test::{App, BankSudo, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, BankSudo, Executor}; +use dao_testing::contracts::cw20_base_contract; use crate::CheckedDenom; -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - #[test] fn test_cw20_denom_send() { let mut app = App::default(); - let cw20_id = app.store_code(cw20_contract()); + let cw20_id = app.store_code(cw20_base_contract()); let cw20 = app .instantiate_contract( cw20_id, diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index 9b191be86..35b1521b8 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -1,6 +1,9 @@ [package] name = "dao-testing" -authors = ["ekez ekez@withoutdoing.com", "Jake Hartnell "] +authors = [ + "ekez ekez@withoutdoing.com", + "Jake Hartnell ", +] description = "Testing helper functions and interfaces for testing DAO modules." edition = { workspace = true } license = { workspace = true } @@ -36,21 +39,30 @@ rand = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } +btsg-ft-factory = { workspace = true } cw-admin-factory = { workspace = true } -cw-core-v1 = { workspace = true, features = ["library"] } +cw-fund-distributor = { workspace = true } cw-hooks = { workspace = true } -cw-proposal-single-v1 = { workspace = true } +cw-payroll-factory = { workspace = true } +cw-token-swap = { workspace = true } cw-vesting = { workspace = true } cw20-stake = { workspace = true } +cw20-stake-external-rewards = { workspace = true } cw721-base = { workspace = true } cw721-roles = { workspace = true } cw-tokenfactory-issuer = { workspace = true } -dao-dao-core = { workspace = true, features = ["library"] } +dao-dao-core = { workspace = true } dao-interface = { workspace = true } +dao-migrator = { workspace = true } +dao-pre-propose-approver = { workspace = true } dao-pre-propose-multiple = { workspace = true } dao-pre-propose-single = { workspace = true } +dao-pre-propose-approval-single = { workspace = true } dao-proposal-condorcet = { workspace = true } dao-proposal-single = { workspace = true } +dao-proposal-multiple = { workspace = true } +dao-proposal-sudo = { workspace = true } +dao-rewards-distributor = { workspace = true } dao-test-custom-factory = { workspace = true } dao-voting = { workspace = true } dao-voting-cw20-balance = { workspace = true } @@ -60,5 +72,24 @@ dao-voting-cw721-staked = { workspace = true } dao-voting-cw721-roles = { workspace = true } dao-voting-onft-staked = { workspace = true } dao-voting-token-staked = { workspace = true } -voting-v1 = { workspace = true } +dao-proposal-hook-counter = { workspace = true } + +# v1 migration +cw-core-v1 = { workspace = true } +cw-proposal-single-v1 = { workspace = true } +cw4-voting-v1 = { workspace = true } +cw20-stake-v1 = { workspace = true } +cw20-stake-external-rewards-v1 = { workspace = true } stake-cw20-v03 = { workspace = true } +voting-v1 = { workspace = true } + +# v2.4.1 migration +dao-dao-core-v241 = { workspace = true } +dao-interface-v241 = { workspace = true } +dao-pre-propose-approval-single-v241 = { workspace = true } +dao-pre-propose-single-v241 = { workspace = true } +dao-pre-propose-multiple-v241 = { workspace = true } +dao-proposal-single-v241 = { workspace = true } +dao-proposal-multiple-v241 = { workspace = true } +dao-voting-cw4-v241 = { workspace = true } +dao-voting-v241 = { workspace = true } diff --git a/packages/dao-testing/src/contracts.rs b/packages/dao-testing/src/contracts.rs deleted file mode 100644 index 1739ed124..000000000 --- a/packages/dao-testing/src/contracts.rs +++ /dev/null @@ -1,218 +0,0 @@ -use cosmwasm_std::Empty; - -use cw_multi_test::{Contract, ContractWrapper}; -use dao_pre_propose_multiple as cppm; -use dao_pre_propose_single as cpps; - -pub fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -pub fn cw4_group_contract() -> Box> { - let contract = ContractWrapper::new( - cw4_group::contract::execute, - cw4_group::contract::instantiate, - cw4_group::contract::query, - ); - Box::new(contract) -} - -pub fn cw721_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw721_base::entry::execute, - cw721_base::entry::instantiate, - cw721_base::entry::query, - ); - Box::new(contract) -} - -pub fn cw721_roles_contract() -> Box> { - let contract = ContractWrapper::new( - cw721_roles::contract::execute, - cw721_roles::contract::instantiate, - cw721_roles::contract::query, - ); - Box::new(contract) -} - -pub fn cw20_stake_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_stake::contract::execute, - cw20_stake::contract::instantiate, - cw20_stake::contract::query, - ); - Box::new(contract) -} - -pub fn proposal_condorcet_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_condorcet::contract::execute, - dao_proposal_condorcet::contract::instantiate, - dao_proposal_condorcet::contract::query, - ) - .with_reply(dao_proposal_condorcet::contract::reply); - Box::new(contract) -} - -pub fn proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - dao_proposal_single::contract::execute, - dao_proposal_single::contract::instantiate, - dao_proposal_single::contract::query, - ) - .with_reply(dao_proposal_single::contract::reply) - .with_migrate(dao_proposal_single::contract::migrate); - Box::new(contract) -} - -pub fn pre_propose_single_contract() -> Box> { - let contract = ContractWrapper::new( - cpps::contract::execute, - cpps::contract::instantiate, - cpps::contract::query, - ); - Box::new(contract) -} - -pub fn pre_propose_multiple_contract() -> Box> { - let contract = ContractWrapper::new( - cppm::contract::execute, - cppm::contract::instantiate, - cppm::contract::query, - ); - Box::new(contract) -} - -pub fn cw20_staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_staked::contract::execute, - dao_voting_cw20_staked::contract::instantiate, - dao_voting_cw20_staked::contract::query, - ) - .with_reply(dao_voting_cw20_staked::contract::reply); - Box::new(contract) -} - -pub fn cw20_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw20_balance::contract::execute, - dao_voting_cw20_balance::contract::instantiate, - dao_voting_cw20_balance::contract::query, - ) - .with_reply(dao_voting_cw20_balance::contract::reply); - Box::new(contract) -} - -pub fn native_staked_balances_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_token_staked::contract::execute, - dao_voting_token_staked::contract::instantiate, - dao_voting_token_staked::contract::query, - ) - .with_reply(dao_voting_token_staked::contract::reply); - Box::new(contract) -} - -pub fn cw721_staked_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw721_staked::contract::execute, - dao_voting_cw721_staked::contract::instantiate, - dao_voting_cw721_staked::contract::query, - ) - .with_reply(dao_voting_cw721_staked::contract::reply); - Box::new(contract) -} - -pub fn onft_staked_voting_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_onft_staked::contract::execute, - dao_voting_onft_staked::contract::instantiate, - dao_voting_onft_staked::contract::query, - ); - Box::new(contract) -} - -pub fn dao_dao_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} - -pub fn dao_voting_cw4_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw4::contract::execute, - dao_voting_cw4::contract::instantiate, - dao_voting_cw4::contract::query, - ) - .with_reply(dao_voting_cw4::contract::reply); - Box::new(contract) -} - -pub fn dao_voting_cw721_roles_contract() -> Box> { - let contract = ContractWrapper::new( - dao_voting_cw721_roles::contract::execute, - dao_voting_cw721_roles::contract::instantiate, - dao_voting_cw721_roles::contract::query, - ) - .with_reply(dao_voting_cw721_roles::contract::reply); - Box::new(contract) -} - -pub fn v1_proposal_single_contract() -> Box> { - let contract = ContractWrapper::new( - cw_proposal_single_v1::contract::execute, - cw_proposal_single_v1::contract::instantiate, - cw_proposal_single_v1::contract::query, - ) - .with_reply(cw_proposal_single_v1::contract::reply) - .with_migrate(cw_proposal_single_v1::contract::migrate); - Box::new(contract) -} - -pub fn v1_dao_dao_contract() -> Box> { - let contract = ContractWrapper::new( - cw_core_v1::contract::execute, - cw_core_v1::contract::instantiate, - cw_core_v1::contract::query, - ) - .with_reply(cw_core_v1::contract::reply); - Box::new(contract) -} - -pub fn cw_vesting_contract() -> Box> { - let contract = ContractWrapper::new( - cw_vesting::contract::execute, - cw_vesting::contract::instantiate, - cw_vesting::contract::query, - ); - Box::new(contract) -} - -pub fn stake_cw20_v03_contract() -> Box> { - let contract = ContractWrapper::new( - stake_cw20_v03::contract::execute, - stake_cw20_v03::contract::instantiate, - stake_cw20_v03::contract::query, - ); - Box::new(contract) -} - -pub fn dao_test_custom_factory() -> Box> { - let contract = ContractWrapper::new( - dao_test_custom_factory::contract::execute, - dao_test_custom_factory::contract::instantiate, - dao_test_custom_factory::contract::query, - ) - .with_reply(dao_test_custom_factory::contract::reply); - Box::new(contract) -} diff --git a/packages/dao-testing/src/contracts/latest.rs b/packages/dao-testing/src/contracts/latest.rs new file mode 100644 index 000000000..86faadca8 --- /dev/null +++ b/packages/dao-testing/src/contracts/latest.rs @@ -0,0 +1,326 @@ +use cosmwasm_std::Empty; +use cw_multi_test::{Contract, ContractWrapper}; + +pub fn cw20_base_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ) + .with_migrate(cw20_base::contract::migrate); + Box::new(contract) +} + +pub fn cw4_group_contract() -> Box> { + let contract = ContractWrapper::new( + cw4_group::contract::execute, + cw4_group::contract::instantiate, + cw4_group::contract::query, + ); + Box::new(contract) +} + +pub fn cw721_base_contract() -> Box> { + let contract = ContractWrapper::new( + cw721_base::entry::execute, + cw721_base::entry::instantiate, + cw721_base::entry::query, + ) + .with_migrate(cw721_base::entry::migrate); + Box::new(contract) +} + +pub fn cw721_roles_contract() -> Box> { + let contract = ContractWrapper::new( + cw721_roles::contract::execute, + cw721_roles::contract::instantiate, + cw721_roles::contract::query, + ); + Box::new(contract) +} + +pub fn cw20_stake_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_stake::contract::execute, + cw20_stake::contract::instantiate, + cw20_stake::contract::query, + ) + .with_migrate(cw20_stake::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_condorcet_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_condorcet::contract::execute, + dao_proposal_condorcet::contract::instantiate, + dao_proposal_condorcet::contract::query, + ) + .with_reply(dao_proposal_condorcet::contract::reply); + Box::new(contract) +} + +pub fn dao_proposal_single_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_single::contract::execute, + dao_proposal_single::contract::instantiate, + dao_proposal_single::contract::query, + ) + .with_reply(dao_proposal_single::contract::reply) + .with_migrate(dao_proposal_single::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_multiple_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_multiple::contract::execute, + dao_proposal_multiple::contract::instantiate, + dao_proposal_multiple::contract::query, + ) + .with_reply(dao_proposal_multiple::contract::reply) + .with_migrate(dao_proposal_multiple::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_sudo_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_sudo::contract::execute, + dao_proposal_sudo::contract::instantiate, + dao_proposal_sudo::contract::query, + ); + Box::new(contract) +} + +pub fn dao_pre_propose_approver_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_approver::contract::execute, + dao_pre_propose_approver::contract::instantiate, + dao_pre_propose_approver::contract::query, + ) + .with_migrate(dao_pre_propose_approver::contract::migrate); + Box::new(contract) +} + +pub fn dao_pre_propose_single_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_single::contract::execute, + dao_pre_propose_single::contract::instantiate, + dao_pre_propose_single::contract::query, + ) + .with_migrate(dao_pre_propose_single::contract::migrate); + Box::new(contract) +} + +pub fn dao_pre_propose_multiple_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_multiple::contract::execute, + dao_pre_propose_multiple::contract::instantiate, + dao_pre_propose_multiple::contract::query, + ) + .with_migrate(dao_pre_propose_multiple::contract::migrate); + Box::new(contract) +} + +pub fn dao_pre_propose_approval_single_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_approval_single::contract::execute, + dao_pre_propose_approval_single::contract::instantiate, + dao_pre_propose_approval_single::contract::query, + ) + .with_migrate(dao_pre_propose_approval_single::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw4_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw4::contract::execute, + dao_voting_cw4::contract::instantiate, + dao_voting_cw4::contract::query, + ) + .with_reply(dao_voting_cw4::contract::reply) + .with_migrate(dao_voting_cw4::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw20_staked_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw20_staked::contract::execute, + dao_voting_cw20_staked::contract::instantiate, + dao_voting_cw20_staked::contract::query, + ) + .with_reply(dao_voting_cw20_staked::contract::reply) + .with_migrate(dao_voting_cw20_staked::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw20_balance_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw20_balance::contract::execute, + dao_voting_cw20_balance::contract::instantiate, + dao_voting_cw20_balance::contract::query, + ) + .with_reply(dao_voting_cw20_balance::contract::reply); + Box::new(contract) +} + +pub fn dao_voting_token_staked_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_token_staked::contract::execute, + dao_voting_token_staked::contract::instantiate, + dao_voting_token_staked::contract::query, + ) + .with_reply(dao_voting_token_staked::contract::reply) + .with_migrate(dao_voting_token_staked::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw721_staked_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw721_staked::contract::execute, + dao_voting_cw721_staked::contract::instantiate, + dao_voting_cw721_staked::contract::query, + ) + .with_reply(dao_voting_cw721_staked::contract::reply) + .with_migrate(dao_voting_cw721_staked::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw721_roles_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw721_roles::contract::execute, + dao_voting_cw721_roles::contract::instantiate, + dao_voting_cw721_roles::contract::query, + ) + .with_reply(dao_voting_cw721_roles::contract::reply); + Box::new(contract) +} + +pub fn dao_voting_onft_staked_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_onft_staked::contract::execute, + dao_voting_onft_staked::contract::instantiate, + dao_voting_onft_staked::contract::query, + ) + .with_migrate(dao_voting_onft_staked::contract::migrate); + Box::new(contract) +} + +pub fn dao_dao_core_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core::contract::execute, + dao_dao_core::contract::instantiate, + dao_dao_core::contract::query, + ) + .with_reply(dao_dao_core::contract::reply) + .with_migrate(dao_dao_core::contract::migrate); + Box::new(contract) +} + +pub fn dao_migrator_contract() -> Box> { + let contract = ContractWrapper::new( + dao_migrator::contract::execute, + dao_migrator::contract::instantiate, + dao_migrator::contract::query, + ) + .with_reply(dao_migrator::contract::reply); + Box::new(contract) +} + +pub fn cw_vesting_contract() -> Box> { + let contract = ContractWrapper::new( + cw_vesting::contract::execute, + cw_vesting::contract::instantiate, + cw_vesting::contract::query, + ); + Box::new(contract) +} + +pub fn dao_test_custom_factory_contract() -> Box> { + let contract = ContractWrapper::new( + dao_test_custom_factory::contract::execute, + dao_test_custom_factory::contract::instantiate, + dao_test_custom_factory::contract::query, + ) + .with_reply(dao_test_custom_factory::contract::reply); + Box::new(contract) +} + +pub fn cw_fund_distributor_contract() -> Box> { + let contract = ContractWrapper::new( + cw_fund_distributor::contract::execute, + cw_fund_distributor::contract::instantiate, + cw_fund_distributor::contract::query, + ) + .with_migrate(cw_fund_distributor::contract::migrate); + Box::new(contract) +} + +pub fn dao_rewards_distributor_contract() -> Box> { + let contract = ContractWrapper::new( + dao_rewards_distributor::contract::execute, + dao_rewards_distributor::contract::instantiate, + dao_rewards_distributor::contract::query, + ) + .with_migrate(dao_rewards_distributor::contract::migrate); + Box::new(contract) +} + +pub fn btsg_ft_factory_contract() -> Box> { + let contract = ContractWrapper::new( + btsg_ft_factory::contract::execute, + btsg_ft_factory::contract::instantiate, + btsg_ft_factory::contract::query, + ) + .with_reply(btsg_ft_factory::contract::reply) + .with_migrate(btsg_ft_factory::contract::migrate); + Box::new(contract) +} + +pub fn cw_admin_factory_contract() -> Box> { + let contract = ContractWrapper::new( + cw_admin_factory::contract::execute, + cw_admin_factory::contract::instantiate, + cw_admin_factory::contract::query, + ) + .with_reply(cw_admin_factory::contract::reply) + .with_migrate(cw_admin_factory::contract::migrate); + Box::new(contract) +} + +pub fn cw_payroll_factory_contract() -> Box> { + let contract = ContractWrapper::new( + cw_payroll_factory::contract::execute, + cw_payroll_factory::contract::instantiate, + cw_payroll_factory::contract::query, + ) + .with_reply(cw_payroll_factory::contract::reply); + Box::new(contract) +} + +pub fn cw_token_swap_contract() -> Box> { + let contract = ContractWrapper::new( + cw_token_swap::contract::execute, + cw_token_swap::contract::instantiate, + cw_token_swap::contract::query, + ) + .with_migrate(cw_token_swap::contract::migrate); + Box::new(contract) +} + +pub fn cw20_stake_external_rewards_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_stake_external_rewards::contract::execute, + cw20_stake_external_rewards::contract::instantiate, + cw20_stake_external_rewards::contract::query, + ) + .with_migrate(cw20_stake_external_rewards::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_hook_counter_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_hook_counter::contract::execute, + dao_proposal_hook_counter::contract::instantiate, + dao_proposal_hook_counter::contract::query, + ); + Box::new(contract) +} diff --git a/packages/dao-testing/src/contracts/mod.rs b/packages/dao-testing/src/contracts/mod.rs new file mode 100644 index 000000000..51019ef32 --- /dev/null +++ b/packages/dao-testing/src/contracts/mod.rs @@ -0,0 +1,6 @@ +mod latest; + +pub mod v1; +pub mod v241; + +pub use latest::*; diff --git a/packages/dao-testing/src/contracts/v1.rs b/packages/dao-testing/src/contracts/v1.rs new file mode 100644 index 000000000..daa016102 --- /dev/null +++ b/packages/dao-testing/src/contracts/v1.rs @@ -0,0 +1,64 @@ +use cosmwasm_std::Empty; +use cw_multi_test::{Contract, ContractWrapper}; + +pub fn cw_proposal_single_v1_contract() -> Box> { + let contract = ContractWrapper::new( + cw_proposal_single_v1::contract::execute, + cw_proposal_single_v1::contract::instantiate, + cw_proposal_single_v1::contract::query, + ) + .with_reply(cw_proposal_single_v1::contract::reply) + .with_migrate(cw_proposal_single_v1::contract::migrate); + Box::new(contract) +} + +pub fn cw_core_v1_contract() -> Box> { + let contract = ContractWrapper::new( + cw_core_v1::contract::execute, + cw_core_v1::contract::instantiate, + cw_core_v1::contract::query, + ) + .with_reply(cw_core_v1::contract::reply) + .with_migrate(cw_core_v1::contract::migrate); + Box::new(contract) +} + +pub fn cw4_voting_v1_contract() -> Box> { + let contract = ContractWrapper::new( + cw4_voting_v1::contract::execute, + cw4_voting_v1::contract::instantiate, + cw4_voting_v1::contract::query, + ) + .with_reply(cw4_voting_v1::contract::reply) + .with_migrate(cw4_voting_v1::contract::migrate); + Box::new(contract) +} + +pub fn cw20_stake_v1_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_stake_v1::contract::execute, + cw20_stake_v1::contract::instantiate, + cw20_stake_v1::contract::query, + ) + .with_migrate(cw20_stake_v1::contract::migrate); + Box::new(contract) +} + +pub fn stake_cw20_v03_contract() -> Box> { + let contract = ContractWrapper::new( + stake_cw20_v03::contract::execute, + stake_cw20_v03::contract::instantiate, + stake_cw20_v03::contract::query, + ); + Box::new(contract) +} + +pub fn cw20_stake_external_rewards_v1_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_stake_external_rewards_v1::contract::execute, + cw20_stake_external_rewards_v1::contract::instantiate, + cw20_stake_external_rewards_v1::contract::query, + ) + .with_migrate(cw20_stake_external_rewards_v1::contract::migrate); + Box::new(contract) +} diff --git a/packages/dao-testing/src/contracts/v241.rs b/packages/dao-testing/src/contracts/v241.rs new file mode 100644 index 000000000..51d8b69ac --- /dev/null +++ b/packages/dao-testing/src/contracts/v241.rs @@ -0,0 +1,73 @@ +use cosmwasm_std::Empty; +use cw_multi_test::{Contract, ContractWrapper}; + +pub fn dao_dao_core_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core_v241::contract::execute, + dao_dao_core_v241::contract::instantiate, + dao_dao_core_v241::contract::query, + ) + .with_reply(dao_dao_core_v241::contract::reply) + .with_migrate(dao_dao_core_v241::contract::migrate); + Box::new(contract) +} + +pub fn dao_voting_cw4_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_cw4_v241::contract::execute, + dao_voting_cw4_v241::contract::instantiate, + dao_voting_cw4_v241::contract::query, + ) + .with_reply(dao_voting_cw4_v241::contract::reply) + .with_migrate(dao_voting_cw4_v241::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_single_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_single_v241::contract::execute, + dao_proposal_single_v241::contract::instantiate, + dao_proposal_single_v241::contract::query, + ) + .with_reply(dao_proposal_single_v241::contract::reply) + .with_migrate(dao_proposal_single_v241::contract::migrate); + Box::new(contract) +} + +pub fn dao_proposal_multiple_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_multiple_v241::contract::execute, + dao_proposal_multiple_v241::contract::instantiate, + dao_proposal_multiple_v241::contract::query, + ) + .with_reply(dao_proposal_multiple_v241::contract::reply) + .with_migrate(dao_proposal_multiple_v241::contract::migrate); + Box::new(contract) +} + +pub fn dao_pre_propose_single_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_single_v241::contract::execute, + dao_pre_propose_single_v241::contract::instantiate, + dao_pre_propose_single_v241::contract::query, + ); + Box::new(contract) +} + +pub fn dao_pre_propose_approval_single_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_approval_single_v241::contract::execute, + dao_pre_propose_approval_single_v241::contract::instantiate, + dao_pre_propose_approval_single_v241::contract::query, + ); + Box::new(contract) +} + +pub fn dao_pre_propose_multiple_v241_contract() -> Box> { + let contract = ContractWrapper::new( + dao_pre_propose_multiple_v241::contract::execute, + dao_pre_propose_multiple_v241::contract::instantiate, + dao_pre_propose_multiple_v241::contract::query, + ); + Box::new(contract) +} diff --git a/packages/dao-testing/src/helpers.rs b/packages/dao-testing/src/helpers.rs index b629e7ba0..e44c0a787 100644 --- a/packages/dao-testing/src/helpers.rs +++ b/packages/dao-testing/src/helpers.rs @@ -7,9 +7,8 @@ use dao_voting::threshold::ActiveThreshold; use dao_voting_cw4::msg::GroupContract; use crate::contracts::{ - cw20_balances_voting_contract, cw20_base_contract, cw20_stake_contract, - cw20_staked_balances_voting_contract, cw4_group_contract, dao_dao_contract, - dao_voting_cw4_contract, + cw20_base_contract, cw20_stake_contract, cw4_group_contract, dao_dao_core_contract, + dao_voting_cw20_balance_contract, dao_voting_cw20_staked_contract, dao_voting_cw4_contract, }; const CREATOR_ADDR: &str = "creator"; @@ -21,8 +20,8 @@ pub fn instantiate_with_cw20_balances_governance( initial_balances: Option>, ) -> Addr { let cw20_id = app.store_code(cw20_base_contract()); - let core_id = app.store_code(dao_dao_contract()); - let votemod_id = app.store_code(cw20_balances_voting_contract()); + let core_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_balance_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![Cw20Coin { @@ -125,8 +124,8 @@ pub fn instantiate_with_staked_balances_governance( let cw20_id = app.store_code(cw20_base_contract()); let cw20_stake_id = app.store_code(cw20_stake_contract()); - let staked_balances_voting_id = app.store_code(cw20_staked_balances_voting_contract()); - let core_contract_id = app.store_code(dao_dao_contract()); + let staked_balances_voting_id = app.store_code(dao_voting_cw20_staked_contract()); + let core_contract_id = app.store_code(dao_dao_core_contract()); let instantiate_core = dao_interface::msg::InstantiateMsg { dao_uri: None, @@ -233,8 +232,8 @@ pub fn instantiate_with_staking_active_threshold( ) -> Addr { let cw20_id = app.store_code(cw20_base_contract()); let cw20_staking_id = app.store_code(cw20_stake_contract()); - let governance_id = app.store_code(dao_dao_contract()); - let votemod_id = app.store_code(cw20_staked_balances_voting_contract()); + let governance_id = app.store_code(dao_dao_core_contract()); + let votemod_id = app.store_code(dao_voting_cw20_staked_contract()); let initial_balances = initial_balances.unwrap_or_else(|| { vec![ @@ -307,7 +306,7 @@ pub fn instantiate_with_cw4_groups_governance( initial_weights: Option>, ) -> Addr { let cw4_id = app.store_code(cw4_group_contract()); - let core_id = app.store_code(dao_dao_contract()); + let core_id = app.store_code(dao_dao_core_contract()); let votemod_id = app.store_code(dao_voting_cw4_contract()); let initial_weights = initial_weights.unwrap_or_default(); diff --git a/scripts/publish.sh b/scripts/publish.sh index 4eb17e1e6..604440d36 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -31,7 +31,7 @@ START_DIR=$(pwd) # Packages cd packages/cw-denom -cargo publish +cargo hack publish --no-dev-deps --allow-dirty cd "$START_DIR" cd packages/cw-hooks