diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 04d49c8fb..ee3475659 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -29,15 +29,6 @@ jobs: env: RUST_BACKTRACE: 1 - - name: Run tests w/o default features - uses: actions-rs/cargo@v1 - with: - toolchain: nightly - command: unit-test - args: --locked --no-default-features - env: - RUST_BACKTRACE: 1 - - name: Compile WASM contract uses: actions-rs/cargo@v1 with: @@ -76,13 +67,6 @@ jobs: command: clippy args: --all-targets -- -D warnings - - name: Run cargo clippy w/o default features - uses: actions-rs/cargo@v1 - with: - toolchain: nightly - command: clippy - args: --all-targets --no-default-features -- -D warnings - - name: Generate Schema run: ./scripts/schema.sh diff --git a/contracts/dao-core/Cargo.toml b/contracts/dao-core/Cargo.toml index 561ce6164..73e9eb962 100644 --- a/contracts/dao-core/Cargo.toml +++ b/contracts/dao-core/Cargo.toml @@ -12,11 +12,8 @@ crate-type = ["cdylib", "rlib"] [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] -# enables cw20 treasury management -cw20 = [] # use library feature to disable all instantiate/execute/query exports library = [] -default = ["cw20"] [dependencies] cosmwasm-std = { workspace = true, features = ["ibc3"] } diff --git a/contracts/dao-core/README.md b/contracts/dao-core/README.md index d4d1cac31..72e1bfbd9 100644 --- a/contracts/dao-core/README.md +++ b/contracts/dao-core/README.md @@ -11,75 +11,3 @@ In additon to the wiki spec this contract may also pause. To do so a `Pause` message must by executed by a proposal module. Pausing the core module will stop all actions on the module for the duration of the pause. - -## Treasury management - -For management of non-native assets this contract maintains a list of -[cw20](https://github.com/CosmWasm/cw-plus/tree/1568d9f7796ef93747e5e5e45484447fddbea80b/packages/cw20) -and -[cw721](https://github.com/CosmWasm/cw-nfts/tree/c7be7aba9fb270abefee5a3696be62f2736592a0/packages/cw721) -tokens who's balances the DAO would like to track. This allows -frontends to list these tokens in the DAO's treasury. This tracking is -needed as, for non-native tokens, there is no on-chain data source for -all of the cw20 and cw721 tokens owned by a DAO. It may also help -reduce spam as random shitcoins sent to the DAO won't be displayed in -treasury listings, unless the DAO approves them. - -For native tokens we do not need this additional tracking step, as -native token balances are stored in the [bank -module](https://github.com/cosmos/cosmos-sdk/tree/main/x/bank). Thus, -for those tokens frontends can query the chain directly to discover -which tokens the DAO owns. - -### Managing the treasury - -There are two ways that a non-native token may be added to the DAO -treasury. - -If `automatically_add_[cw20s|cw721s]` is set to true in the [DAO's -config](https://github.com/DA0-DA0/dao-contracts/blob/74bd3881fdd86829e5e8b132b9952dd64f2d0737/contracts/dao-core/src/state.rs#L16-L21), -the DAO will add the token to the treasury upon receiving the token -via cw20's `Send` method and cw721's `SendNft` method. - -``` -pub enum ExecuteMsg { - /// Executed when the contract receives a cw20 token. Depending on - /// the contract's configuration the contract will automatically - /// add the token to its treasury. - #[cfg(feature = "cw20")] - Receive(cw20::Cw20ReceiveMsg), - /// Executed when the contract receives a cw721 token. Depending - /// on the contract's configuration the contract will - /// automatically add the token to its treasury. - ReceiveNft(cw721::Cw721ReceiveMsg), - // ... -} -``` - -The DAO may always add or remove non-native tokens via the -`UpdateCw20List` and `UpdateCw721List` methods: - -```rust -pub enum ExecuteMsg { - /// Updates the list of cw20 tokens this contract has registered. - #[cfg(feature = "cw20")] - UpdateCw20List { - to_add: Vec, - to_remove: Vec, - }, - /// Updates the list of cw721 tokens this contract has registered. - UpdateCw721List { - to_add: Vec, - to_remove: Vec, - }, - // ... -} -``` - -### Disabling cw20 support - -There is an effort on CosmWasm chains to depreciate the cw20 standard -in favor of native tokens [generated by the TokenFactory -module](https://hackmd.io/@reecepbcups/cw20-to-tokenfactory). By -default, this contract has cw20 support. It may be disabled by -disabling default features (ex. `cargo build --no-default-features`). diff --git a/contracts/dao-core/src/contract.rs b/contracts/dao-core/src/contract.rs index 73612f842..90abc6dd1 100644 --- a/contracts/dao-core/src/contract.rs +++ b/contracts/dao-core/src/contract.rs @@ -13,17 +13,13 @@ use dao_interface::{voting, ModuleInstantiateCallback, ModuleInstantiateInfo}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InitialItem, InstantiateMsg, MigrateMsg, QueryMsg}; -#[cfg(feature = "cw20")] -use crate::query::Cw20BalanceResponse; use crate::query::{ - AdminNominationResponse, DaoURIResponse, DumpStateResponse, GetItemResponse, PauseInfoResponse, - SubDao, + AdminNominationResponse, Cw20BalanceResponse, DaoURIResponse, DumpStateResponse, + GetItemResponse, PauseInfoResponse, SubDao, }; -#[cfg(feature = "cw20")] -use crate::state::CW20_LIST; use crate::state::{ Config, ProposalModule, ProposalModuleStatus, ACTIVE_PROPOSAL_MODULE_COUNT, ADMIN, CONFIG, - CW721_LIST, ITEMS, NOMINATED_ADMIN, PAUSED, PROPOSAL_MODULES, SUBDAO_LIST, + CW20_LIST, CW721_LIST, ITEMS, NOMINATED_ADMIN, PAUSED, PROPOSAL_MODULES, SUBDAO_LIST, TOTAL_PROPOSAL_MODULE_COUNT, VOTING_MODULE, }; @@ -47,7 +43,6 @@ pub fn instantiate( name: msg.name, description: msg.description, image_url: msg.image_url, - #[cfg(feature = "cw20")] automatically_add_cw20s: msg.automatically_add_cw20s, automatically_add_cw721s: msg.automatically_add_cw721s, dao_uri: msg.dao_uri, @@ -114,7 +109,6 @@ pub fn execute( execute_proposal_hook(deps.as_ref(), info.sender, msgs) } ExecuteMsg::Pause { duration } => execute_pause(deps, env, info.sender, duration), - #[cfg(feature = "cw20")] ExecuteMsg::Receive(_) => execute_receive_cw20(deps, info.sender), ExecuteMsg::ReceiveNft(_) => execute_receive_cw721(deps, info.sender), ExecuteMsg::RemoveItem { key } => execute_remove_item(deps, env, info.sender, key), @@ -122,7 +116,6 @@ pub fn execute( ExecuteMsg::UpdateConfig { config } => { execute_update_config(deps, env, info.sender, config) } - #[cfg(feature = "cw20")] ExecuteMsg::UpdateCw20List { to_add, to_remove } => { execute_update_cw20_list(deps, env, info.sender, to_add, to_remove) } @@ -404,7 +397,6 @@ fn do_update_addr_list( Ok(()) } -#[cfg(feature = "cw20")] pub fn execute_update_cw20_list( deps: DepsMut, env: Env, @@ -512,7 +504,6 @@ pub fn execute_update_sub_daos_list( .add_attribute("sender", sender)) } -#[cfg(feature = "cw20")] pub fn execute_receive_cw20(deps: DepsMut, sender: Addr) -> Result { let config = CONFIG.load(deps.storage)?; if !config.automatically_add_cw20s { @@ -543,9 +534,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Admin {} => query_admin(deps), QueryMsg::AdminNomination {} => query_admin_nomination(deps), QueryMsg::Config {} => query_config(deps), - #[cfg(feature = "cw20")] QueryMsg::Cw20TokenList { start_after, limit } => query_cw20_list(deps, start_after, limit), - #[cfg(feature = "cw20")] QueryMsg::Cw20Balances { start_after, limit } => { query_cw20_balances(deps, env, start_after, limit) } @@ -738,7 +727,6 @@ pub fn query_list_items( )?) } -#[cfg(feature = "cw20")] pub fn query_cw20_list( deps: Deps, start_after: Option, @@ -771,7 +759,6 @@ pub fn query_cw721_list( )?) } -#[cfg(feature = "cw20")] pub fn query_cw20_balances( deps: Deps, env: Env, @@ -879,7 +866,6 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result, to_remove: Vec, @@ -148,7 +145,6 @@ pub enum QueryMsg { Config {}, /// Gets the token balance for each cw20 registered with the /// contract. - #[cfg(feature = "cw20")] #[returns(crate::query::Cw20BalanceResponse)] Cw20Balances { start_after: Option, @@ -156,7 +152,6 @@ pub enum QueryMsg { }, /// Lists the addresses of the cw20 tokens in this contract's /// treasury. - #[cfg(feature = "cw20")] #[returns(Vec)] Cw20TokenList { start_after: Option, diff --git a/contracts/dao-core/src/query.rs b/contracts/dao-core/src/query.rs index 49af9c149..e3a43f02c 100644 --- a/contracts/dao-core/src/query.rs +++ b/contracts/dao-core/src/query.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; +use cosmwasm_std::{Addr, Uint128}; use cw2::ContractVersion; use cw_utils::Expiration; @@ -45,12 +45,11 @@ pub struct GetItemResponse { /// Returned by the `Cw20Balances` query. #[cw_serde] -#[cfg(feature = "cw20")] pub struct Cw20BalanceResponse { /// The address of the token. pub addr: Addr, /// The contract's balance. - pub balance: cosmwasm_std::Uint128, + pub balance: Uint128, } /// Returned by the `AdminNomination` query. diff --git a/contracts/dao-core/src/state.rs b/contracts/dao-core/src/state.rs index 43b88370f..3bc0bdfbc 100644 --- a/contracts/dao-core/src/state.rs +++ b/contracts/dao-core/src/state.rs @@ -15,7 +15,6 @@ pub struct Config { pub image_url: Option, /// If true the contract will automatically add received cw20 /// tokens to its treasury. - #[cfg(feature = "cw20")] pub automatically_add_cw20s: bool, /// If true the contract will automatically add received cw721 /// tokens to its treasury. @@ -25,8 +24,8 @@ pub struct Config { pub dao_uri: Option, } -/// Top level type describing a proposal module. #[cw_serde] +/// Top level type describing a proposal module. pub struct ProposalModule { /// The address of the proposal module. pub address: Addr, @@ -37,8 +36,8 @@ pub struct ProposalModule { pub status: ProposalModuleStatus, } -/// The status of a proposal module. #[cw_serde] +/// The status of a proposal module. pub enum ProposalModuleStatus { Enabled, Disabled, @@ -87,7 +86,6 @@ pub const ITEMS: Map = Map::new("items"); /// Set of cw20 tokens that have been registered with this contract's /// treasury. -#[cfg(feature = "cw20")] pub const CW20_LIST: Map = Map::new("cw20s"); /// Set of cw721 tokens that have been registered with this contract's /// treasury. diff --git a/contracts/dao-core/src/tests.rs b/contracts/dao-core/src/tests.rs index d5f31217d..e50f409f6 100644 --- a/contracts/dao-core/src/tests.rs +++ b/contracts/dao-core/src/tests.rs @@ -13,15 +13,12 @@ use dao_interface::{ Admin, ModuleInstantiateInfo, }; -#[cfg(feature = "cw20")] -use crate::query::Cw20BalanceResponse; - use crate::{ contract::{derive_proposal_module_prefix, migrate, CONTRACT_NAME, CONTRACT_VERSION}, msg::{ExecuteMsg, InitialItem, InstantiateMsg, MigrateMsg, QueryMsg}, query::{ - AdminNominationResponse, DaoURIResponse, DumpStateResponse, GetItemResponse, - PauseInfoResponse, SubDao, + AdminNominationResponse, Cw20BalanceResponse, DaoURIResponse, DumpStateResponse, + GetItemResponse, PauseInfoResponse, SubDao, }, state::{Config, ProposalModule, ProposalModuleStatus, PROPOSAL_MODULES}, ContractError, @@ -116,7 +113,6 @@ fn test_instantiate_with_n_gov_modules(n: usize) { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -149,7 +145,6 @@ fn test_instantiate_with_n_gov_modules(n: usize) { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, } @@ -221,7 +216,6 @@ makes wickedness." name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -252,7 +246,6 @@ fn test_update_config() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -298,7 +291,6 @@ fn test_update_config() { name: "Root DAO".to_string(), description: "We love trees and sudo.".to_string(), image_url: Some("https://moonphase.is/image.svg".to_string()), - #[cfg(feature = "cw20")] automatically_add_cw20s: false, automatically_add_cw721s: true, dao_uri: Some("https://daostar.one/EIP".to_string()), @@ -351,7 +343,6 @@ fn test_swap_governance(swaps: Vec<(u32, u32)>) { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -504,7 +495,6 @@ fn test_removed_modules_can_not_execute() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -662,7 +652,6 @@ fn test_module_already_disabled() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -762,7 +751,6 @@ fn test_swap_voting_module() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -879,7 +867,6 @@ fn test_permissions() { label: "governance module".to_string(), }], initial_items: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, }; @@ -926,7 +913,6 @@ fn test_permissions() { name: "Evil config.".to_string(), description: "👿".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, }, @@ -965,7 +951,6 @@ fn do_standard_instantiate(auto_add: bool, admin: Option) -> (Addr, App) name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: auto_add, automatically_add_cw721s: auto_add, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -1598,7 +1583,6 @@ fn test_list_items() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -1716,7 +1700,6 @@ fn test_instantiate_with_items() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -1777,7 +1760,6 @@ fn test_instantiate_with_items() { assert_eq!(item1_value, Some("item1_value".to_string())) } -#[cfg(feature = "cw20")] #[test] fn test_cw20_receive_auto_add() { let (gov_addr, mut app) = do_standard_instantiate(true, None); @@ -1813,21 +1795,19 @@ fn test_cw20_receive_auto_add() { ) .unwrap(); - #[cfg(feature = "cw20")] - { - // Check that the balances query works with no tokens. - let cw20_balances: Vec = app - .wrap() - .query_wasm_smart( - gov_addr.clone(), - &QueryMsg::Cw20Balances { - start_after: None, - limit: None, - }, - ) - .unwrap(); - assert_eq!(cw20_balances, vec![]); - } + // Check that the balances query works with no tokens. + let cw20_balances: Vec = app + .wrap() + .query_wasm_smart( + gov_addr.clone(), + &QueryMsg::Cw20Balances { + start_after: None, + limit: None, + }, + ) + .unwrap(); + assert_eq!(cw20_balances, vec![]); + // Send a gov token to the governance contract. app.execute_contract( Addr::unchecked(CREATOR_ADDR), @@ -1927,7 +1907,6 @@ fn test_cw20_receive_auto_add() { assert_eq!(cw20_list, vec![another_cw20]); } -#[cfg(feature = "cw20")] #[test] fn test_cw20_receive_no_auto_add() { let (gov_addr, mut app) = do_standard_instantiate(false, None); @@ -2294,7 +2273,6 @@ fn test_pause() { name: "The Empire Strikes Back".to_string(), description: "haha lol we have pwned your DAO".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, }, @@ -2371,7 +2349,6 @@ fn test_pause() { name: "The Empire Strikes Back Again".to_string(), description: "haha lol we have pwned your DAO again".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, }, @@ -2549,7 +2526,6 @@ fn test_migrate_from_compatible() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: false, automatically_add_cw721s: false, voting_module_instantiate_info: ModuleInstantiateInfo { @@ -2748,7 +2724,6 @@ fn test_migrate_mock() { assert_eq!(v2_config.name, v1_config.name); assert_eq!(v2_config.description, v1_config.description); assert_eq!(v2_config.image_url, v1_config.image_url); - #[cfg(feature = "cw20")] assert_eq!( v2_config.automatically_add_cw20s, v1_config.automatically_add_cw20s @@ -2807,7 +2782,6 @@ fn test_module_prefixes() { name: "DAO DAO".to_string(), description: "A DAO that builds DAOs.".to_string(), image_url: None, - #[cfg(feature = "cw20")] automatically_add_cw20s: true, automatically_add_cw721s: true, voting_module_instantiate_info: ModuleInstantiateInfo {