From c8f686fae904927226ee8b6a7e7025122cfb10bc Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Mon, 22 Apr 2024 20:42:39 -0500 Subject: [PATCH] Revert support for initial supply --- contracts/external/cw-abc/schema/cw-abc.json | 169 ++------------- contracts/external/cw-abc/src/abc.rs | 9 +- contracts/external/cw-abc/src/contract.rs | 195 +++--------------- contracts/external/cw-abc/src/msg.rs | 6 +- contracts/external/cw-abc/src/queries.rs | 8 +- contracts/external/cw-abc/src/state.rs | 11 +- .../cw-abc/src/test_tube/integration_tests.rs | 159 +------------- .../external/cw-abc/src/test_tube/test_env.rs | 67 +----- contracts/external/cw-abc/src/testing.rs | 12 +- .../dao-abc-factory/src/test_tube/test_env.rs | 25 +-- .../src/testing/instantiate.rs | 2 +- .../src/testing/instantiate.rs | 2 +- .../dao-voting-token-staked/src/contract.rs | 4 +- .../voting/dao-voting-token-staked/src/msg.rs | 23 ++- .../dao-voting-token-staked/src/state.rs | 3 +- .../src/tests/multitest/tests.rs | 3 +- .../src/tests/test_tube/integration_tests.rs | 4 +- .../src/tests/test_tube/test_env.rs | 4 +- packages/dao-interface/src/token.rs | 21 +- 19 files changed, 117 insertions(+), 610 deletions(-) diff --git a/contracts/external/cw-abc/schema/cw-abc.json b/contracts/external/cw-abc/schema/cw-abc.json index fd14e69cd..79d409cb8 100644 --- a/contracts/external/cw-abc/schema/cw-abc.json +++ b/contracts/external/cw-abc/schema/cw-abc.json @@ -10,7 +10,8 @@ "curve_type", "phase_config", "reserve", - "supply" + "supply", + "token_issuer_code_id" ], "properties": { "curve_type": { @@ -61,14 +62,16 @@ "$ref": "#/definitions/SupplyToken" } ] + }, + "token_issuer_code_id": { + "description": "The code id of the cw-tokenfactory-issuer contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, "ClosedConfig": { "type": "object", "additionalProperties": false @@ -336,22 +339,6 @@ }, "additionalProperties": false }, - "InitialBalance": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, "MinMax": { "description": "Struct for minimum and maximum values", "type": "object", @@ -407,56 +394,6 @@ }, "additionalProperties": false }, - "NewTokenInfo": { - "type": "object", - "required": [ - "initial_balances", - "subdenom", - "token_issuer_code_id" - ], - "properties": { - "initial_balances": { - "description": "The initial balances to set for the token, cannot be empty.", - "type": "array", - "items": { - "$ref": "#/definitions/InitialBalance" - } - }, - "initial_dao_balance": { - "description": "Optional balance to mint for the DAO.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "metadata": { - "description": "Optional metadata for the token, this can additionally be set later.", - "anyOf": [ - { - "$ref": "#/definitions/NewDenomMetadata" - }, - { - "type": "null" - } - ] - }, - "subdenom": { - "description": "The subdenom of the token to create, will also be used as an alias for the denom. The Token Factory denom will have the format of factory/{contract_address}/{subdenom}", - "type": "string" - }, - "token_issuer_code_id": { - "description": "The code id of the cw-tokenfactory-issuer contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, "OpenConfig": { "type": "object", "required": [ @@ -507,7 +444,7 @@ "type": "object", "required": [ "decimals", - "token_info" + "subdenom" ], "properties": { "decimals": { @@ -526,70 +463,24 @@ } ] }, - "token_info": { - "description": "New or existing native token NOTE: If using an existing token, then the ABC must be given mint and burn permissions after creation", - "allOf": [ + "metadata": { + "description": "Metadata for the supply token to create", + "anyOf": [ { - "$ref": "#/definitions/TokenInfo" + "$ref": "#/definitions/NewDenomMetadata" + }, + { + "type": "null" } ] + }, + "subdenom": { + "description": "The denom to create for the supply token", + "type": "string" } }, "additionalProperties": false }, - "TokenInfo": { - "oneOf": [ - { - "description": "Uses an existing Token Factory token and creates a new issuer contract. Full setup, such as transferring ownership or setting up MsgSetBeforeSendHook, must be done manually.", - "type": "object", - "required": [ - "existing" - ], - "properties": { - "existing": { - "type": "object", - "required": [ - "denom" - ], - "properties": { - "denom": { - "description": "Token factory denom", - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates a new Token Factory token via the issue contract with the DAO automatically setup as admin and owner.", - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/NewTokenInfo" - } - }, - "additionalProperties": false - }, - { - "description": "Uses a factory contract that must return the denom, optionally a Token Contract address. The binary must serialize to a `WasmMsg::Execute` message. Validation happens in the factory contract itself, so be sure to use a trusted factory contract.", - "type": "object", - "required": [ - "factory" - ], - "properties": { - "factory": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" @@ -1447,20 +1338,6 @@ }, "additionalProperties": false }, - { - "description": "Returns the Initial Supply of the supply token when the ABC was created", - "type": "object", - "required": [ - "initial_supply" - ], - "properties": { - "initial_supply": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "description": "Returns the Maximum Supply of the supply token", "type": "object", @@ -1921,12 +1798,6 @@ } } }, - "initial_supply": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Uint128", - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, "is_paused": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Boolean", diff --git a/contracts/external/cw-abc/src/abc.rs b/contracts/external/cw-abc/src/abc.rs index 8d7f570a9..5fec074a1 100644 --- a/contracts/external/cw-abc/src/abc.rs +++ b/contracts/external/cw-abc/src/abc.rs @@ -5,15 +5,16 @@ use cw_curves::{ utils::decimal, Curve, DecimalPlaces, }; -use dao_interface::token::TokenInfo; +use dao_interface::token::NewDenomMetadata; use crate::ContractError; #[cw_serde] pub struct SupplyToken { - /// New or existing native token - /// NOTE: If using an existing token, then the ABC must be given mint and burn permissions after creation - pub token_info: TokenInfo, + /// The denom to create for the supply token + pub subdenom: String, + /// Metadata for the supply token to create + pub metadata: Option, /// Number of decimal places for the supply token, needed for proper curve math. /// Default for token factory is 6 pub decimals: u8, diff --git a/contracts/external/cw-abc/src/contract.rs b/contracts/external/cw-abc/src/contract.rs index 7b06d84b5..2916ced81 100644 --- a/contracts/external/cw-abc/src/contract.rs +++ b/contracts/external/cw-abc/src/contract.rs @@ -10,14 +10,13 @@ use cw_tokenfactory_issuer::msg::{ DenomUnit, ExecuteMsg as IssuerExecuteMsg, InstantiateMsg as IssuerInstantiateMsg, Metadata, }; use cw_utils::parse_reply_instantiate_data; -use dao_interface::token::{InitialBalance, TokenInfo}; use crate::abc::{CommonsPhase, CurveFn}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{ - CurveState, CURVE_STATE, CURVE_TYPE, FUNDING_POOL_FORWARDING, INITIAL_SUPPLY, IS_PAUSED, - MAX_SUPPLY, NEW_TOKEN_INFO, PHASE, PHASE_CONFIG, SUPPLY_DENOM, TOKEN_ISSUER_CONTRACT, + CurveState, CURVE_STATE, CURVE_TYPE, FUNDING_POOL_FORWARDING, IS_PAUSED, MAX_SUPPLY, PHASE, + PHASE_CONFIG, SUPPLY_DENOM, TEMP_SUPPLY, TOKEN_ISSUER_CONTRACT, }; use crate::{commands, queries}; @@ -37,6 +36,7 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let InstantiateMsg { + token_issuer_code_id, funding_pool_forwarding, supply, reserve, @@ -55,15 +55,10 @@ pub fn instantiate( )?; } - if let TokenInfo::New(new_token_info) = &supply.token_info { - if new_token_info.subdenom.is_empty() { - return Err(ContractError::SupplyTokenError( - "Token subdenom must not be empty.".to_string(), - )); - } - - // Save new token info for use in reply - NEW_TOKEN_INFO.save(deps.storage, new_token_info)?; + if supply.subdenom.is_empty() { + return Err(ContractError::SupplyTokenError( + "Token subdenom must not be empty.".to_string(), + )); } if let Some(max_supply) = supply.max_supply { @@ -96,66 +91,23 @@ pub fn instantiate( let normalization_places = DecimalPlaces::new(supply.decimals, reserve.decimals); let curve_state = CurveState::new(reserve.denom, normalization_places); - let msgs = match supply.token_info { - // Instantiate cw-token-factory-issuer contract if new - TokenInfo::New(new_token_info) => vec![SubMsg::reply_always( - WasmMsg::Instantiate { - // Contract is immutable, no admin - admin: None, - code_id: new_token_info.token_issuer_code_id, - msg: to_json_binary(&IssuerInstantiateMsg::NewToken { - subdenom: new_token_info.subdenom, - })?, - funds: info.funds, - label: "cw-tokenfactory-issuer".to_string(), - }, - INSTANTIATE_TOKEN_FACTORY_ISSUER_REPLY_ID, - )], - TokenInfo::Existing { denom } => { - if !denom.starts_with("factory/") { - return Err(ContractError::SupplyTokenError( - "Token must be issued by the tokenfactory".to_string(), - )); - } - - // 'factory/' length is 8, so we trim that off - let issuer_subdenom = &denom[8..]; - - // Get a validated issuer from the expected [issuer]/[subdenom] string - let issuer = match issuer_subdenom.find('/') { - Some(end_index) => { - let issuer = deps.api.addr_validate(&issuer_subdenom[..end_index])?; - - // Query for the existing supply - let existing_supply = deps.querier.query_supply(&denom)?; - - // Validate max supply - if let Some(max_supply) = supply.max_supply { - let max_mint_supply = - curve_type.to_curve_fn()(curve_state.clone().decimals) - .supply(phase_config.hatch.initial_raise.max); - - if existing_supply.amount.checked_add(max_mint_supply)? > max_supply { - return Err(ContractError::CannotExceedMaxSupply { max: max_supply }); - } - } - - // Set the initial supply - INITIAL_SUPPLY.save(deps.storage, &existing_supply.amount)?; - - Ok(issuer) - } - None => Err(ContractError::SupplyTokenError( - "Tokenfactory denom did not contain a subdenom".to_string(), - )), - }?; - - TOKEN_ISSUER_CONTRACT.save(deps.storage, &issuer)?; - - vec![] - } - TokenInfo::Factory(_) => unimplemented!(), - }; + // Save subdenom for handling in the reply + TEMP_SUPPLY.save(deps.storage, &supply)?; + + // Instantiate cw-token-factory-issuer contract + let msg = SubMsg::reply_always( + WasmMsg::Instantiate { + // Contract is immutable, no admin + admin: None, + code_id: token_issuer_code_id, + msg: to_json_binary(&IssuerInstantiateMsg::NewToken { + subdenom: supply.subdenom, + })?, + funds: info.funds, + label: "cw-tokenfactory-issuer".to_string(), + }, + INSTANTIATE_TOKEN_FACTORY_ISSUER_REPLY_ID, + ); // Save the curve state CURVE_STATE.save(deps.storage, &curve_state)?; @@ -163,7 +115,7 @@ pub fn instantiate( // Set the paused state IS_PAUSED.save(deps.storage, &false)?; - Ok(Response::default().add_submessages(msgs)) + Ok(Response::default().add_submessage(msg)) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -243,7 +195,6 @@ pub fn do_query(deps: Deps, _env: Env, msg: QueryMsg, curve_fn: CurveFn) -> StdR config_type, )?), QueryMsg::IsPaused {} => to_json_binary(&IS_PAUSED.load(deps.storage)?), - QueryMsg::InitialSupply {} => to_json_binary(&queries::query_initial_supply(deps)?), QueryMsg::MaxSupply {} => to_json_binary(&queries::query_max_supply(deps)?), QueryMsg::Ownership {} => to_json_binary(&cw_ownable::get_ownership(deps.storage)?), QueryMsg::PhaseConfig {} => to_json_binary(&queries::query_phase_config(deps)?), @@ -267,13 +218,15 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result Result Result max_supply { - return Err(ContractError::CannotExceedMaxSupply { max: max_supply }); - } - } - - if !initial_supply.is_zero() { - // Set the initial supply - INITIAL_SUPPLY.save(deps.storage, &initial_supply)?; - - // Call issuer contract to mint tokens for initial balances - new_token_info - .initial_balances - .iter() - .for_each(|b: &InitialBalance| { - msgs.push(WasmMsg::Execute { - contract_addr: issuer_addr.clone(), - msg: to_json_binary(&IssuerExecuteMsg::Mint { - to_address: b.address.clone(), - amount: b.amount, - }) - .unwrap_or_default(), - funds: vec![], - }); - }); - - // Add initial DAO balance to initial_balances if nonzero. - if let Some(initial_dao_balance) = new_token_info.initial_dao_balance { - if !initial_dao_balance.is_zero() { - // In this case, it would be considered the funding pool - if let Some(funding_pool_forwarding) = - FUNDING_POOL_FORWARDING.may_load(deps.storage)? - { - msgs.push(WasmMsg::Execute { - contract_addr: issuer_addr.clone(), - msg: to_json_binary(&IssuerExecuteMsg::Mint { - to_address: funding_pool_forwarding.to_string(), - amount: initial_dao_balance, - })?, - funds: vec![], - }); - } else { - CURVE_STATE.update( - deps.storage, - |mut curve_state| -> StdResult<_> { - curve_state.funding = initial_dao_balance; - - Ok(curve_state) - }, - )?; - msgs.push(WasmMsg::Execute { - contract_addr: issuer_addr.clone(), - msg: to_json_binary(&IssuerExecuteMsg::Mint { - to_address: env.contract.address.to_string(), - amount: initial_dao_balance, - })?, - funds: vec![], - }); - } - } - } - } - Ok(Response::new() .add_attribute("cw-tokenfactory-issuer-address", issuer_addr) .add_attribute("denom", denom) diff --git a/contracts/external/cw-abc/src/msg.rs b/contracts/external/cw-abc/src/msg.rs index 0b1751a58..2116153d0 100644 --- a/contracts/external/cw-abc/src/msg.rs +++ b/contracts/external/cw-abc/src/msg.rs @@ -10,6 +10,9 @@ use crate::{ #[cw_serde] pub struct InstantiateMsg { + /// The code id of the cw-tokenfactory-issuer contract + pub token_issuer_code_id: u64, + /// An optional address for automatically forwarding funding pool gains pub funding_pool_forwarding: Option, @@ -150,9 +153,6 @@ pub enum QueryMsg { limit: Option, config_type: Option, }, - /// Returns the Initial Supply of the supply token when the ABC was created - #[returns(Uint128)] - InitialSupply {}, /// Returns the Maximum Supply of the supply token #[returns(Uint128)] MaxSupply {}, diff --git a/contracts/external/cw-abc/src/queries.rs b/contracts/external/cw-abc/src/queries.rs index 6a5defc21..c95d0a5e6 100644 --- a/contracts/external/cw-abc/src/queries.rs +++ b/contracts/external/cw-abc/src/queries.rs @@ -5,7 +5,7 @@ use crate::msg::{ }; use crate::state::{ hatcher_allowlist, CurveState, HatcherAllowlistConfigType, CURVE_STATE, DONATIONS, HATCHERS, - INITIAL_SUPPLY, MAX_SUPPLY, PHASE, PHASE_CONFIG, SUPPLY_DENOM, + MAX_SUPPLY, PHASE, PHASE_CONFIG, SUPPLY_DENOM, }; use cosmwasm_std::{Addr, Deps, Order, QuerierWrapper, StdResult, Uint128}; use cw_storage_plus::Bound; @@ -125,12 +125,6 @@ pub fn query_hatcher_allowlist( }) } -/// Query the initial supply of the supply token when the ABC was created -pub fn query_initial_supply(deps: Deps) -> StdResult { - let initial_supply = INITIAL_SUPPLY.may_load(deps.storage)?; - Ok(initial_supply.unwrap_or_default()) -} - /// Query the max supply of the supply token pub fn query_max_supply(deps: Deps) -> StdResult { let max_supply = MAX_SUPPLY.may_load(deps.storage)?; diff --git a/contracts/external/cw-abc/src/state.rs b/contracts/external/cw-abc/src/state.rs index 864e5f4d3..2e7462219 100644 --- a/contracts/external/cw-abc/src/state.rs +++ b/contracts/external/cw-abc/src/state.rs @@ -1,9 +1,7 @@ use std::fmt::{self, Display}; +use crate::abc::{CommonsPhase, CommonsPhaseConfig, CurveType, SupplyToken}; use cosmwasm_schema::cw_serde; -use dao_interface::token::NewTokenInfo; - -use crate::abc::{CommonsPhase, CommonsPhaseConfig, CurveType}; use cosmwasm_std::{Addr, Uint128}; use cw_curves::DecimalPlaces; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; @@ -98,9 +96,6 @@ pub const FUNDING_POOL_FORWARDING: Item = Item::new("funding_pool_forwardi /// The denom used for the supply token pub const SUPPLY_DENOM: Item = Item::new("denom"); -/// The initial supply of the supply token when the ABC was created -pub const INITIAL_SUPPLY: Item = Item::new("initial_supply"); - /// The maximum supply of the supply token, new tokens cannot be minted beyond this cap pub const MAX_SUPPLY: Item = Item::new("max_supply"); @@ -118,8 +113,8 @@ pub static PHASE_CONFIG: Item = Item::new("phase_config"); /// The phase state of the Augmented Bonding Curve pub static PHASE: Item = Item::new("phase"); -/// Temporarily holds NewTokenInfo when creating a new Token Factory denom -pub const NEW_TOKEN_INFO: Item = Item::new("new_token_info"); +/// Temporarily holds the supply config when creating a new Token Factory denom +pub const TEMP_SUPPLY: Item = Item::new("temp_supply"); /// The address of the cw-tokenfactory-issuer contract pub const TOKEN_ISSUER_CONTRACT: Item = Item::new("token_issuer_contract"); diff --git a/contracts/external/cw-abc/src/test_tube/integration_tests.rs b/contracts/external/cw-abc/src/test_tube/integration_tests.rs index 7466cd7d9..104501169 100644 --- a/contracts/external/cw-abc/src/test_tube/integration_tests.rs +++ b/contracts/external/cw-abc/src/test_tube/integration_tests.rs @@ -15,7 +15,6 @@ use super::test_env::{TestEnv, TestEnvBuilder, DENOM, RESERVE}; use cosmwasm_std::{coins, Decimal, Uint128}; use cw_tokenfactory_issuer::msg::QueryMsg as IssuerQueryMsg; -use dao_interface::token::{NewTokenInfo, TokenInfo}; use osmosis_std::types::cosmos::bank::v1beta1::QueryBalanceRequest; use osmosis_test_tube::{osmosis_std::types::cosmos::base::v1beta1::Coin, Account, OsmosisTestApp}; @@ -282,15 +281,11 @@ fn test_allowlist() { let app = OsmosisTestApp::new(); let builder = TestEnvBuilder::new(); let instantiate_msg = InstantiateMsg { + token_issuer_code_id: 0, funding_pool_forwarding: Some("replaced to accounts[0]".to_string()), supply: SupplyToken { - token_info: TokenInfo::New(NewTokenInfo { - token_issuer_code_id: 0, - subdenom: DENOM.to_string(), - metadata: None, - initial_balances: vec![], - initial_dao_balance: None, - }), + subdenom: DENOM.to_string(), + metadata: None, decimals: 6, max_supply: Some(Uint128::from(1000000000u128)), }, @@ -546,151 +541,3 @@ fn test_update_curve() { }) ); } - -#[test] -fn test_existing_token_failures() { - let app = OsmosisTestApp::new(); - let builder = TestEnvBuilder::new(); - - // The tokenfactory token does not exist - fails in supply query - let mut instantiate_msg = InstantiateMsg { - funding_pool_forwarding: Some("replaced to accounts[0]".to_string()), - supply: SupplyToken { - token_info: TokenInfo::Existing { - denom: "factory/address/nonexistent".to_string(), - }, - decimals: 6, - max_supply: Some(Uint128::from(1000000000u128)), - }, - reserve: ReserveToken { - denom: RESERVE.to_string(), - decimals: 6, - }, - phase_config: CommonsPhaseConfig { - hatch: HatchConfig { - contribution_limits: MinMax { - min: Uint128::from(10u128), - max: Uint128::from(1000000u128), - }, - initial_raise: MinMax { - min: Uint128::from(10u128), - max: Uint128::from(1000000u128), - }, - entry_fee: Decimal::percent(10u64), - exit_fee: Decimal::percent(10u64), - }, - open: OpenConfig { - entry_fee: Decimal::percent(10u64), - exit_fee: Decimal::percent(10u64), - }, - closed: ClosedConfig {}, - }, - hatcher_allowlist: None, - curve_type: CurveType::Constant { - value: Uint128::one(), - scale: 1, - }, - }; - let result = builder.setup(&app, instantiate_msg.clone()); - assert!(result.is_err()); - - // A subdenom is required - let builder = TestEnvBuilder::new(); - instantiate_msg.supply.token_info = TokenInfo::Existing { - denom: "factory/malformed".to_string(), - }; - let result = builder.setup(&app, instantiate_msg.clone()); - assert!(result.is_err()); - - // Only tokenfactory tokens are supported - let builder = TestEnvBuilder::new(); - instantiate_msg.supply.token_info = TokenInfo::Existing { - denom: "junox".to_string(), - }; - let result = builder.setup(&app, instantiate_msg.clone()); - assert!(result.is_err()); -} - -#[test] -fn test_existing_token() { - let app = OsmosisTestApp::new(); - let builder = TestEnvBuilder::new(); - - let result = builder.setup_with_token( - &app, - InstantiateMsg { - funding_pool_forwarding: Some("replaced to accounts[0]".to_string()), - supply: SupplyToken { - token_info: TokenInfo::Existing { - denom: "replaced".to_string(), - }, - decimals: 6, - max_supply: None, - }, - reserve: ReserveToken { - denom: RESERVE.to_string(), - decimals: 6, - }, - phase_config: CommonsPhaseConfig { - hatch: HatchConfig { - contribution_limits: MinMax { - min: Uint128::from(10u128), - max: Uint128::from(1000000u128), - }, - initial_raise: MinMax { - min: Uint128::from(10u128), - max: Uint128::from(1000000u128), - }, - entry_fee: Decimal::percent(10u64), - exit_fee: Decimal::percent(10u64), - }, - open: OpenConfig { - entry_fee: Decimal::percent(10u64), - exit_fee: Decimal::percent(10u64), - }, - closed: ClosedConfig {}, - }, - hatcher_allowlist: None, - curve_type: CurveType::Constant { - value: Uint128::one(), - scale: 1, - }, - }, - ); - assert!(result.is_ok()); - let TestEnv { - ref abc, - ref accounts, - ref tf_issuer, - .. - } = result.unwrap(); - - let denom_response: DenomResponse = tf_issuer - .query(&cw_tokenfactory_issuer::msg::QueryMsg::Denom {}) - .unwrap(); - let _denom = format!( - "factory/{}/{}", - tf_issuer.contract_addr, denom_response.denom - ); - - // Allow the ABC to modify the supply - let result = tf_issuer.execute( - &cw_tokenfactory_issuer::msg::ExecuteMsg::SetMinterAllowance { - address: abc.contract_addr.clone(), - allowance: Uint128::MAX, - }, - &[], - &accounts[0], - ); - assert!(result.is_ok()); - - let result = tf_issuer.execute( - &cw_tokenfactory_issuer::msg::ExecuteMsg::SetBurnerAllowance { - address: abc.contract_addr.clone(), - allowance: Uint128::MAX, - }, - &[], - &accounts[0], - ); - assert!(result.is_ok()); -} diff --git a/contracts/external/cw-abc/src/test_tube/test_env.rs b/contracts/external/cw-abc/src/test_tube/test_env.rs index 865c20357..f6502282e 100644 --- a/contracts/external/cw-abc/src/test_tube/test_env.rs +++ b/contracts/external/cw-abc/src/test_tube/test_env.rs @@ -12,7 +12,6 @@ use crate::{ }; use cosmwasm_std::{Coin, Decimal, Uint128}; -use dao_interface::token::{NewTokenInfo, TokenInfo}; use dao_testing::test_tube::cw_tokenfactory_issuer::TokenfactoryIssuer; use osmosis_test_tube::{ osmosis_std::types::cosmos::bank::v1beta1::QueryAllBalancesRequest, @@ -106,15 +105,11 @@ impl TestEnvBuilder { let abc = CwAbc::deploy( app, &InstantiateMsg { + token_issuer_code_id: issuer_id, funding_pool_forwarding: Some(accounts[0].address()), supply: SupplyToken { - token_info: TokenInfo::New(NewTokenInfo { - token_issuer_code_id: issuer_id, - subdenom: DENOM.to_string(), - metadata: None, - initial_balances: vec![], - initial_dao_balance: None, - }), + subdenom: DENOM.to_string(), + metadata: None, decimals: 6, max_supply: Some(Uint128::from(1000000000u128)), }, @@ -174,10 +169,7 @@ impl TestEnvBuilder { let issuer_id = TokenfactoryIssuer::upload(app, &accounts[0])?; - // Override issuer_id and fees_recipient - if let TokenInfo::New(ref mut new_token_info) = msg.supply.token_info { - new_token_info.token_issuer_code_id = issuer_id; - } + msg.token_issuer_code_id = issuer_id; msg.funding_pool_forwarding = Some(accounts[0].address()); @@ -195,57 +187,6 @@ impl TestEnvBuilder { }) } - pub fn setup_with_token( - self, - app: &'_ OsmosisTestApp, - mut msg: InstantiateMsg, - ) -> Result, RunnerError> { - let accounts = app - .init_accounts(&[Coin::new(1000000000000000u128, RESERVE)], 10) - .unwrap(); - - let tf_issuer: TokenfactoryIssuer = TokenfactoryIssuer::new( - app, - &cw_tokenfactory_issuer::msg::InstantiateMsg::NewToken { - subdenom: "subdenom".to_string(), - }, - &accounts[0], - )?; - - msg.funding_pool_forwarding = Some(accounts[0].address()); - - msg.supply.token_info = TokenInfo::Existing { - denom: format!("factory/{}/{}", tf_issuer.contract_addr, "subdenom"), - }; - - // Accounts[0] has minted some tokens to themselves - tf_issuer.execute( - &cw_tokenfactory_issuer::msg::ExecuteMsg::SetMinterAllowance { - address: accounts[0].address().to_string(), - allowance: Uint128::MAX, - }, - &[], - &accounts[0], - )?; - tf_issuer.execute( - &cw_tokenfactory_issuer::msg::ExecuteMsg::Mint { - to_address: accounts[0].address().to_string(), - amount: Uint128::new(1_000_000u128), - }, - &[], - &accounts[0], - )?; - - let abc = CwAbc::deploy(app, &msg, &accounts[0])?; - - Ok(TestEnv { - app, - abc, - tf_issuer, - accounts, - }) - } - pub fn upload_issuer(self, app: &'_ OsmosisTestApp, signer: &SigningAccount) -> u64 { TokenfactoryIssuer::upload(app, signer).unwrap() } diff --git a/contracts/external/cw-abc/src/testing.rs b/contracts/external/cw-abc/src/testing.rs index ff204ae9a..6d867888d 100644 --- a/contracts/external/cw-abc/src/testing.rs +++ b/contracts/external/cw-abc/src/testing.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{ testing::{mock_env, mock_info}, Decimal, DepsMut, Response, Uint128, }; -use dao_interface::token::{NewDenomMetadata, NewTokenInfo, TokenInfo}; +use dao_interface::token::NewDenomMetadata; use crate::contract; use crate::msg::InstantiateMsg; @@ -42,15 +42,11 @@ pub fn default_instantiate_msg( curve_type: CurveType, ) -> InstantiateMsg { InstantiateMsg { + token_issuer_code_id: 1, funding_pool_forwarding: None, supply: SupplyToken { - token_info: TokenInfo::New(NewTokenInfo { - token_issuer_code_id: 1, - subdenom: TEST_SUPPLY_DENOM.to_string(), - metadata: Some(default_supply_metadata()), - initial_balances: vec![], - initial_dao_balance: None, - }), + subdenom: TEST_SUPPLY_DENOM.to_string(), + metadata: Some(default_supply_metadata()), decimals, max_supply: None, }, diff --git a/contracts/external/dao-abc-factory/src/test_tube/test_env.rs b/contracts/external/dao-abc-factory/src/test_tube/test_env.rs index 88dd27655..ad3f8f847 100644 --- a/contracts/external/dao-abc-factory/src/test_tube/test_env.rs +++ b/contracts/external/dao-abc-factory/src/test_tube/test_env.rs @@ -16,12 +16,11 @@ use cw_utils::Duration; use dao_interface::{ msg::QueryMsg as DaoQueryMsg, state::{Admin, ModuleInstantiateInfo, ProposalModule}, - token::{NewTokenInfo, TokenInfo}, }; use dao_voting::{ pre_propose::PreProposeInfo, threshold::PercentageThreshold, threshold::Threshold, }; -use dao_voting_token_staked::msg::QueryMsg as TokenVotingQueryMsg; +use dao_voting_token_staked::msg::{QueryMsg as TokenVotingQueryMsg, TokenInfo}; use dao_testing::test_tube::{ cw_abc::CwAbc, cw_tokenfactory_issuer::TokenfactoryIssuer, dao_dao_core::DaoCore, @@ -136,17 +135,11 @@ impl TestEnvBuilder { contract_addr: dao_abc_factory.contract_addr.clone(), msg: to_json_binary(&ExecuteMsg::AbcFactory { instantiate_msg: cw_abc::msg::InstantiateMsg { + token_issuer_code_id: issuer_id, funding_pool_forwarding: Some(accounts[0].address()), - supply: SupplyToken { - token_info: TokenInfo::New(NewTokenInfo { - token_issuer_code_id: issuer_id, - subdenom: DENOM.to_string(), - metadata: None, - initial_balances: vec![], - initial_dao_balance: None, - }), - + subdenom: DENOM.to_string(), + metadata: None, decimals: 6, max_supply: Some(Uint128::from(1000000000u128)), }, @@ -254,15 +247,11 @@ impl TestEnvBuilder { contract_addr: dao_abc_factory.contract_addr.clone(), msg: to_json_binary(&ExecuteMsg::AbcFactory { instantiate_msg: cw_abc::msg::InstantiateMsg { + token_issuer_code_id: issuer_id, funding_pool_forwarding: Some(accounts[0].address()), supply: SupplyToken { - token_info: TokenInfo::New(NewTokenInfo { - token_issuer_code_id: issuer_id, - subdenom: DENOM.to_string(), - metadata: None, - initial_balances: vec![], - initial_dao_balance: None, - }), + subdenom: DENOM.to_string(), + metadata: None, decimals: 6, max_supply: Some(Uint128::from(1000000000u128)), }, diff --git a/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs b/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs index 2eb1458bb..8fd7e0c95 100644 --- a/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs +++ b/contracts/proposal/dao-proposal-multiple/src/testing/instantiate.rs @@ -272,7 +272,7 @@ pub fn instantiate_with_native_staked_balances_governance( voting_module_instantiate_info: ModuleInstantiateInfo { code_id: native_stake_id, msg: to_json_binary(&dao_voting_token_staked::msg::InstantiateMsg { - token_info: dao_interface::token::TokenInfo::Existing { + token_info: dao_voting_token_staked::msg::TokenInfo::Existing { denom: "ujuno".to_string(), }, unstaking_duration: None, diff --git a/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs b/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs index ef6fecc96..020154700 100644 --- a/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs +++ b/contracts/proposal/dao-proposal-single/src/testing/instantiate.rs @@ -270,7 +270,7 @@ pub(crate) fn instantiate_with_native_staked_balances_governance( voting_module_instantiate_info: ModuleInstantiateInfo { code_id: native_stake_id, msg: to_json_binary(&dao_voting_token_staked::msg::InstantiateMsg { - token_info: dao_interface::token::TokenInfo::Existing { + token_info: dao_voting_token_staked::msg::TokenInfo::Existing { denom: "ujuno".to_string(), }, unstaking_duration: None, diff --git a/contracts/voting/dao-voting-token-staked/src/contract.rs b/contracts/voting/dao-voting-token-staked/src/contract.rs index 72429742a..53aaae888 100644 --- a/contracts/voting/dao-voting-token-staked/src/contract.rs +++ b/contracts/voting/dao-voting-token-staked/src/contract.rs @@ -17,7 +17,7 @@ use cw_utils::{ use dao_hooks::stake::{stake_hook_msgs, unstake_hook_msgs}; use dao_interface::{ state::ModuleInstantiateCallback, - token::{InitialBalance, NewTokenInfo, TokenFactoryCallback, TokenInfo}, + token::{InitialBalance, NewTokenInfo, TokenFactoryCallback}, voting::{ DenomResponse, IsActiveResponse, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse, }, @@ -30,7 +30,6 @@ use dao_voting::{ }, }; -use crate::error::ContractError; use crate::msg::{ ExecuteMsg, GetHooksResponse, InstantiateMsg, ListStakersResponse, MigrateMsg, QueryMsg, StakerBalanceResponse, @@ -39,6 +38,7 @@ use crate::state::{ Config, ACTIVE_THRESHOLD, CLAIMS, CONFIG, DAO, DENOM, HOOKS, MAX_CLAIMS, STAKED_BALANCES, STAKED_TOTAL, TOKEN_INSTANTIATION_INFO, TOKEN_ISSUER_CONTRACT, }; +use crate::{error::ContractError, msg::TokenInfo}; pub(crate) const CONTRACT_NAME: &str = "crates.io:dao-voting-token-staked"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/contracts/voting/dao-voting-token-staked/src/msg.rs b/contracts/voting/dao-voting-token-staked/src/msg.rs index 60bfe04cf..ac194b885 100644 --- a/contracts/voting/dao-voting-token-staked/src/msg.rs +++ b/contracts/voting/dao-voting-token-staked/src/msg.rs @@ -1,11 +1,30 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Uint128; +use cosmwasm_std::{Binary, Uint128}; use cw_utils::Duration; use dao_dao_macros::{active_query, native_token_query, voting_module_query}; -use dao_interface::token::TokenInfo; +use dao_interface::token::NewTokenInfo; #[allow(unused_imports)] use dao_voting::threshold::{ActiveThreshold, ActiveThresholdResponse}; +#[cw_serde] +pub enum TokenInfo { + /// Uses an existing Token Factory token and creates a new issuer contract. + /// Full setup, such as transferring ownership or setting up MsgSetBeforeSendHook, + /// must be done manually. + Existing { + /// Token factory denom + denom: String, + }, + /// Creates a new Token Factory token via the issue contract with the DAO automatically + /// setup as admin and owner. + New(NewTokenInfo), + /// Uses a factory contract that must return the denom, optionally a Token Contract address. + /// The binary must serialize to a `WasmMsg::Execute` message. + /// Validation happens in the factory contract itself, so be sure to use a + /// trusted factory contract. + Factory(Binary), +} + #[cw_serde] pub struct InstantiateMsg { /// New or existing native token to use for voting power. diff --git a/contracts/voting/dao-voting-token-staked/src/state.rs b/contracts/voting/dao-voting-token-staked/src/state.rs index 155c16513..6fb8bc4a0 100644 --- a/contracts/voting/dao-voting-token-staked/src/state.rs +++ b/contracts/voting/dao-voting-token-staked/src/state.rs @@ -4,9 +4,10 @@ use cw_controllers::Claims; use cw_hooks::Hooks; use cw_storage_plus::{Item, SnapshotItem, SnapshotMap, Strategy}; use cw_utils::Duration; -use dao_interface::token::TokenInfo; use dao_voting::threshold::ActiveThreshold; +use crate::msg::TokenInfo; + #[cw_serde] pub struct Config { pub unstaking_duration: Option, 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 437d4da3a..90b4fab28 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 @@ -1,7 +1,7 @@ use crate::contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}; use crate::msg::{ ExecuteMsg, GetHooksResponse, InstantiateMsg, ListStakersResponse, MigrateMsg, QueryMsg, - StakerBalanceResponse, + StakerBalanceResponse, TokenInfo, }; use crate::state::Config; use cosmwasm_std::testing::{mock_dependencies, mock_env}; @@ -11,7 +11,6 @@ use cw_multi_test::{ next_block, App, AppResponse, BankSudo, Contract, ContractWrapper, Executor, SudoMsg, }; use cw_utils::Duration; -use dao_interface::token::TokenInfo; use dao_interface::voting::{ DenomResponse, InfoResponse, IsActiveResponse, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse, diff --git a/contracts/voting/dao-voting-token-staked/src/tests/test_tube/integration_tests.rs b/contracts/voting/dao-voting-token-staked/src/tests/test_tube/integration_tests.rs index 2fcdb65e2..926abe763 100644 --- a/contracts/voting/dao-voting-token-staked/src/tests/test_tube/integration_tests.rs +++ b/contracts/voting/dao-voting-token-staked/src/tests/test_tube/integration_tests.rs @@ -5,7 +5,7 @@ use cw_utils::Duration; use dao_interface::{ msg::QueryMsg as DaoQueryMsg, state::{Admin, ModuleInstantiateInfo}, - token::{InitialBalance, NewDenomMetadata, NewTokenInfo, TokenInfo}, + token::{InitialBalance, NewDenomMetadata, NewTokenInfo}, }; use dao_testing::test_tube::{cw_tokenfactory_issuer::TokenfactoryIssuer, dao_dao_core::DaoCore}; use dao_voting::{ @@ -18,7 +18,7 @@ use osmosis_test_tube::{ }; use crate::{ - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg, TokenInfo}, tests::test_tube::test_env::TokenVotingContract, ContractError, }; diff --git a/contracts/voting/dao-voting-token-staked/src/tests/test_tube/test_env.rs b/contracts/voting/dao-voting-token-staked/src/tests/test_tube/test_env.rs index 84dd18195..3c93c9ee6 100644 --- a/contracts/voting/dao-voting-token-staked/src/tests/test_tube/test_env.rs +++ b/contracts/voting/dao-voting-token-staked/src/tests/test_tube/test_env.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] use crate::{ - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, + msg::{ExecuteMsg, InstantiateMsg, QueryMsg, TokenInfo}, ContractError, }; @@ -13,7 +13,7 @@ use cw_utils::Duration; use dao_interface::{ msg::QueryMsg as DaoQueryMsg, state::{Admin, ModuleInstantiateInfo, ProposalModule}, - token::{InitialBalance, NewDenomMetadata, NewTokenInfo, TokenInfo}, + token::{InitialBalance, NewDenomMetadata, NewTokenInfo}, voting::{IsActiveResponse, VotingPowerAtHeightResponse}, }; use dao_voting::{ diff --git a/packages/dao-interface/src/token.rs b/packages/dao-interface/src/token.rs index 3a760d6aa..c735a15c4 100644 --- a/packages/dao-interface/src/token.rs +++ b/packages/dao-interface/src/token.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Binary, Uint128}; +use cosmwasm_std::Uint128; // These are Cosmos Proto types used for Denom Metadata. // We re-export them here for convenience. @@ -7,25 +7,6 @@ pub use osmosis_std::types::cosmos::bank::v1beta1::{DenomUnit, Metadata}; use crate::state::ModuleInstantiateCallback; -#[cw_serde] -pub enum TokenInfo { - /// Uses an existing Token Factory token and creates a new issuer contract. - /// Full setup, such as transferring ownership or setting up MsgSetBeforeSendHook, - /// must be done manually. - Existing { - /// Token factory denom - denom: String, - }, - /// Creates a new Token Factory token via the issue contract with the DAO automatically - /// setup as admin and owner. - New(NewTokenInfo), - /// Uses a factory contract that must return the denom, optionally a Token Contract address. - /// The binary must serialize to a `WasmMsg::Execute` message. - /// Validation happens in the factory contract itself, so be sure to use a - /// trusted factory contract. - Factory(Binary), -} - #[cw_serde] pub struct InitialBalance { pub amount: Uint128,