diff --git a/contracts/minter/schema/config.json b/contracts/minter/schema/config.json index 442165825..b778c2ab0 100644 --- a/contracts/minter/schema/config.json +++ b/contracts/minter/schema/config.json @@ -16,14 +16,6 @@ "base_token_uri": { "type": "string" }, - "batch_mint_limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, "num_tokens": { "type": "integer", "format": "uint64", diff --git a/contracts/minter/schema/config_response.json b/contracts/minter/schema/config_response.json index c35076576..bfd7a8de0 100644 --- a/contracts/minter/schema/config_response.json +++ b/contracts/minter/schema/config_response.json @@ -17,14 +17,6 @@ "base_token_uri": { "type": "string" }, - "batch_mint_limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, "num_tokens": { "type": "integer", "format": "uint64", diff --git a/contracts/minter/schema/execute_msg.json b/contracts/minter/schema/execute_msg.json index 5b2a5bef8..4ca56c0a9 100644 --- a/contracts/minter/schema/execute_msg.json +++ b/contracts/minter/schema/execute_msg.json @@ -68,28 +68,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "update_batch_mint_limit" - ], - "properties": { - "update_batch_mint_limit": { - "type": "object", - "required": [ - "batch_mint_limit" - ], - "properties": { - "batch_mint_limit": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -135,28 +113,6 @@ } }, "additionalProperties": false - }, - { - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "num_mints" - ], - "properties": { - "num_mints": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false } ], "definitions": { diff --git a/contracts/minter/schema/instantiate_msg.json b/contracts/minter/schema/instantiate_msg.json index 5b081605b..628739bdc 100644 --- a/contracts/minter/schema/instantiate_msg.json +++ b/contracts/minter/schema/instantiate_msg.json @@ -13,14 +13,6 @@ "base_token_uri": { "type": "string" }, - "batch_mint_limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, "num_tokens": { "type": "integer", "format": "uint64", diff --git a/contracts/minter/src/contract.rs b/contracts/minter/src/contract.rs index d5d4ce228..eba89746d 100644 --- a/contracts/minter/src/contract.rs +++ b/contracts/minter/src/contract.rs @@ -35,8 +35,6 @@ const INSTANTIATE_SG721_REPLY_ID: u64 = 1; // governance parameters const MAX_TOKEN_LIMIT: u32 = 10000; const MAX_PER_ADDRESS_LIMIT: u32 = 30; -const MAX_BATCH_MINT_LIMIT: u32 = 30; -const STARTING_BATCH_MINT_LIMIT: u32 = 5; const STARTING_PER_ADDRESS_LIMIT: u32 = 5; const MIN_MINT_PRICE: u128 = 50_000_000; const MINT_FEE_PERCENT: u32 = 10; @@ -66,16 +64,6 @@ pub fn instantiate( } } - if let Some(batch_mint_limit) = msg.batch_mint_limit { - // Check batch mint limit is valid - if batch_mint_limit > MAX_BATCH_MINT_LIMIT { - return Err(ContractError::InvalidBatchMintLimit { - max: MAX_BATCH_MINT_LIMIT.to_string(), - got: batch_mint_limit.to_string(), - }); - } - } - // Check that base_token_uri is a valid IPFS uri let parsed_token_uri = Url::parse(&msg.base_token_uri)?; if parsed_token_uri.scheme() != "ipfs" { @@ -95,9 +83,6 @@ pub fn instantiate( }); } - // Initially set batch_mint_limit if no msg - let batch_mint_limit: Option = msg.batch_mint_limit.or(Some(STARTING_BATCH_MINT_LIMIT)); - // Initially set per_address_limit if no msg let per_address_limit: Option = msg.per_address_limit.or(Some(STARTING_PER_ADDRESS_LIMIT)); @@ -126,7 +111,6 @@ pub fn instantiate( sg721_code_id: msg.sg721_code_id, unit_price: msg.unit_price, per_address_limit, - batch_mint_limit, whitelist: whitelist_addr, start_time: Some(start_time), }; @@ -179,15 +163,11 @@ pub fn execute( ExecuteMsg::UpdatePerAddressLimit { per_address_limit } => { execute_update_per_address_limit(deps, env, info, per_address_limit) } - ExecuteMsg::UpdateBatchMintLimit { batch_mint_limit } => { - execute_update_batch_mint_limit(deps, env, info, batch_mint_limit) - } ExecuteMsg::MintTo { recipient } => execute_mint_to(deps, env, info, recipient), ExecuteMsg::MintFor { token_id, recipient, } => execute_mint_for(deps, env, info, token_id, recipient), - ExecuteMsg::BatchMint { num_mints } => execute_batch_mint(deps, env, info, num_mints), ExecuteMsg::SetWhitelist { whitelist } => { execute_set_whitelist(deps, env, info, &whitelist) } @@ -337,40 +317,6 @@ pub fn execute_mint_for( ) } -pub fn execute_batch_mint( - deps: DepsMut, - env: Env, - _info: MessageInfo, - num_mints: u32, -) -> Result { - let config = CONFIG.load(deps.storage)?; - let mint_limit = config - .batch_mint_limit - .ok_or(ContractError::MaxBatchMintLimitExceeded {})?; - - if num_mints > mint_limit { - return Err(ContractError::MaxBatchMintLimitExceeded {}); - } - - // NOTE: fees are handled in the `_execute_mint` function - - let mut msgs: Vec> = vec![]; - let mint_msg = ExecuteMsg::Mint {}; - let msg: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: env.contract.address.to_string(), - msg: to_binary(&mint_msg)?, - funds: vec![mint_price(deps.as_ref(), false)?], - }); - for _ in 0..num_mints { - msgs.append(&mut vec![msg.clone()]); - } - - Ok(Response::default() - .add_attribute("action", "batch_mint") - .add_attribute("num_mints", num_mints.to_string()) - .add_messages(msgs)) -} - fn _execute_mint( deps: DepsMut, env: Env, @@ -545,31 +491,6 @@ pub fn execute_update_per_address_limit( .add_attribute("limit", per_address_limit.to_string())) } -pub fn execute_update_batch_mint_limit( - deps: DepsMut, - _env: Env, - info: MessageInfo, - batch_mint_limit: u32, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - if info.sender != config.admin { - return Err(ContractError::Unauthorized( - "Sender is not an admin".to_owned(), - )); - } - if batch_mint_limit > MAX_BATCH_MINT_LIMIT { - return Err(ContractError::InvalidBatchMintLimit { - max: MAX_BATCH_MINT_LIMIT.to_string(), - got: batch_mint_limit.to_string(), - }); - } - config.batch_mint_limit = Some(batch_mint_limit); - CONFIG.save(deps.storage, &config)?; - Ok(Response::new() - .add_attribute("action", "update_batch_mint_limit") - .add_attribute("limit", batch_mint_limit.to_string())) -} - pub fn mint_price(deps: Deps, admin_no_fee: bool) -> Result { // if admin_no_fee => no fee, // else if in whitelist => whitelist price @@ -618,7 +539,6 @@ fn query_config(deps: Deps) -> StdResult { start_time: config.start_time, unit_price: config.unit_price, per_address_limit: config.per_address_limit, - batch_mint_limit: config.batch_mint_limit, whitelist: config.whitelist, }) } diff --git a/contracts/minter/src/contract_tests.rs b/contracts/minter/src/contract_tests.rs index 384cdd988..ec75ae366 100644 --- a/contracts/minter/src/contract_tests.rs +++ b/contracts/minter/src/contract_tests.rs @@ -103,7 +103,6 @@ fn setup_minter_contract( num_tokens, start_time: None, per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "ipfs://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id, @@ -212,7 +211,6 @@ fn initialization() { num_tokens: 100, start_time: None, per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "https://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id: 1, @@ -241,7 +239,6 @@ fn initialization() { num_tokens: 100, start_time: None, per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "ipfs://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id: 1, @@ -269,7 +266,6 @@ fn initialization() { num_tokens: 100, start_time: None, per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "ipfs://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id: 1, @@ -297,7 +293,6 @@ fn initialization() { num_tokens: (MAX_TOKEN_LIMIT + 1).into(), start_time: None, per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "ipfs://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id: 1, @@ -739,169 +734,6 @@ fn check_per_address_limit() { assert!(res.is_err()); } -#[test] -fn batch_mint_limit_access_max_sold_out() { - let mut router = custom_mock_app(); - let (creator, buyer) = setup_accounts(&mut router).unwrap(); - - let creator_balances = router.wrap().query_all_balances(creator.clone()).unwrap(); - assert_eq!( - creator_balances, - coins(INITIAL_BALANCE + CREATION_FEE, NATIVE_DENOM) - ); - - let num_tokens = 4; - let (minter_addr, _config) = setup_minter_contract(&mut router, &creator, num_tokens).unwrap(); - // set to genesis mint start time - setup_block_time(&mut router, GENESIS_MINT_START_TIME).unwrap(); - - // initial + creation fee - creation_fee = 2,000 + 1,000 - 1,000 = 2,000 tokens - let creator_balances = router.wrap().query_all_balances(creator.clone()).unwrap(); - assert_eq!(creator_balances, coins(INITIAL_BALANCE, NATIVE_DENOM)); - - // batch mint limit set to STARTING_BATCH_MINT_LIMIT if no mint provided - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints: 1 }; - let res = router.execute_contract( - buyer.clone(), - minter_addr.clone(), - &batch_mint_msg, - &coins(UNIT_PRICE, NATIVE_DENOM), - ); - assert!(res.is_ok()); - - // update batch mint limit, test unauthorized - let update_batch_mint_limit_msg = ExecuteMsg::UpdateBatchMintLimit { - batch_mint_limit: 1, - }; - let err = router - .execute_contract( - buyer.clone(), - minter_addr.clone(), - &update_batch_mint_limit_msg, - &[], - ) - .unwrap_err(); - assert_eq!( - err.source().unwrap().to_string(), - ContractError::Unauthorized("Sender is not an admin".to_string()).to_string() - ); - - // update limit, invalid limit over max - let update_batch_mint_limit_msg = ExecuteMsg::UpdateBatchMintLimit { - batch_mint_limit: 100, - }; - let err = router - .execute_contract( - creator.clone(), - minter_addr.clone(), - &update_batch_mint_limit_msg, - &[], - ) - .unwrap_err(); - assert_eq!( - ContractError::InvalidBatchMintLimit { - max: 30.to_string(), - got: 100.to_string() - } - .to_string(), - err.source().unwrap().to_string() - ); - - // update limit successfully as admin - let update_batch_mint_limit_msg = ExecuteMsg::UpdateBatchMintLimit { - batch_mint_limit: 2, - }; - let res = router.execute_contract( - creator.clone(), - minter_addr.clone(), - &update_batch_mint_limit_msg, - &[], - ); - assert!(res.is_ok()); - - // test over max batch mint limit - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints: 50 }; - let err = router - .execute_contract( - buyer.clone(), - minter_addr.clone(), - &batch_mint_msg, - &coins(UNIT_PRICE, NATIVE_DENOM), - ) - .unwrap_err(); - assert_eq!( - ContractError::MaxBatchMintLimitExceeded {}.to_string(), - err.source().unwrap().to_string() - ); - - // success - let num_mints = 2; - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints }; - let res = router.execute_contract( - buyer.clone(), - minter_addr.clone(), - &batch_mint_msg, - &coins(UNIT_PRICE * (num_mints as u128), NATIVE_DENOM), - ); - assert!(res.is_ok()); - - // Balances are correct - // Buyer minted 3 times, thus num_mints = num_mints + 1 - let buyer_balances = router.wrap().query_all_balances(buyer.clone()).unwrap(); - assert_eq!( - buyer_balances, - coins( - INITIAL_BALANCE - (UNIT_PRICE * (num_mints + 1) as u128), - NATIVE_DENOM - ) - ); - - // minter contract should have no balance - let minter_balance = router - .wrap() - .query_all_balances(minter_addr.clone()) - .unwrap(); - assert_eq!(0, minter_balance.len()); - - // creator / seller should get tokens from buyer - let creator_balances = router.wrap().query_all_balances(creator.clone()).unwrap(); - assert_eq!( - creator_balances, - coins( - INITIAL_BALANCE + ((UNIT_PRICE - MINT_FEE) * (num_mints + 1) as u128), - NATIVE_DENOM - ) - ); - - // test sold out and fails - let num_mints = 2; - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints }; - let res = router.execute_contract( - buyer.clone(), - minter_addr.clone(), - &batch_mint_msg, - &coins(UNIT_PRICE * num_mints as u128, NATIVE_DENOM), - ); - assert!(res.is_err()); - let err = res.unwrap_err(); - if let Some(nested_err) = err.source() { - assert_eq!( - nested_err.source().unwrap().to_string(), - ContractError::SoldOut {}.to_string(), - ); - }; - - // batch mint smaller amount - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints: 1 }; - let res = router.execute_contract( - buyer, - minter_addr, - &batch_mint_msg, - &coins(UNIT_PRICE, NATIVE_DENOM), - ); - assert!(res.is_ok()); -} - #[test] fn mint_for_token_id_addr() { let mut router = custom_mock_app(); @@ -994,24 +826,11 @@ fn mint_for_token_id_addr() { ); assert!(res.is_ok()); - let num_mints = 2; - let batch_mint_msg = ExecuteMsg::BatchMint { num_mints }; - let res = router.execute_contract( - creator, - minter_addr.clone(), - &batch_mint_msg, - &coins_for_msg(Coin { - amount: Uint128::from(UNIT_PRICE * num_mints as u128), - denom: NATIVE_DENOM.to_string(), - }), - ); - assert!(res.is_ok()); - let mintable_num_tokens_response: MintableNumTokensResponse = router .wrap() .query_wasm_smart(minter_addr, &QueryMsg::MintableNumTokens {}) .unwrap(); - assert_eq!(mintable_num_tokens_response.count, 0); + assert_eq!(mintable_num_tokens_response.count, 2); } #[test] @@ -1033,7 +852,6 @@ fn test_start_time_before_genesis() { GENESIS_MINT_START_TIME - 100, ))), per_address_limit: None, - batch_mint_limit: None, whitelist: None, base_token_uri: "ipfs://QmYxw1rURvnbQbBRTfmVaZtxSrkrfsbodNzibgBrVrUrtN".to_string(), sg721_code_id, diff --git a/contracts/minter/src/error.rs b/contracts/minter/src/error.rs index d0f40b1ab..7aab79fc6 100644 --- a/contracts/minter/src/error.rs +++ b/contracts/minter/src/error.rs @@ -60,12 +60,6 @@ pub enum ContractError { #[error("Max minting limit per address exceeded")] MaxPerAddressLimitExceeded {}, - #[error("Invalid batch mint limit. max: {max}, got: {got}")] - InvalidBatchMintLimit { max: String, got: String }, - - #[error("Max batch mint limit exceeded")] - MaxBatchMintLimitExceeded {}, - #[error("Token id: {token_id} already sold")] TokenIdAlreadySold { token_id: u64 }, diff --git a/contracts/minter/src/msg.rs b/contracts/minter/src/msg.rs index 4cac849e4..b98981172 100644 --- a/contracts/minter/src/msg.rs +++ b/contracts/minter/src/msg.rs @@ -13,7 +13,6 @@ pub struct InstantiateMsg { pub sg721_instantiate_msg: Sg721InstantiateMsg, pub start_time: Option, pub per_address_limit: Option, - pub batch_mint_limit: Option, pub unit_price: Coin, pub whitelist: Option, } @@ -25,10 +24,8 @@ pub enum ExecuteMsg { SetWhitelist { whitelist: String }, UpdateStartTime(Expiration), UpdatePerAddressLimit { per_address_limit: u32 }, - UpdateBatchMintLimit { batch_mint_limit: u32 }, MintTo { recipient: Addr }, MintFor { token_id: u64, recipient: Addr }, - BatchMint { num_mints: u32 }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -44,7 +41,6 @@ pub enum QueryMsg { pub struct ConfigResponse { pub admin: Addr, pub base_token_uri: String, - pub batch_mint_limit: Option, pub num_tokens: u64, pub per_address_limit: Option, pub sg721_address: Addr, diff --git a/contracts/minter/src/state.rs b/contracts/minter/src/state.rs index 89b8dba51..ec1b39124 100644 --- a/contracts/minter/src/state.rs +++ b/contracts/minter/src/state.rs @@ -15,7 +15,6 @@ pub struct Config { pub whitelist: Option, pub start_time: Option, pub per_address_limit: Option, - pub batch_mint_limit: Option, } pub const CONFIG: Item = Item::new("config"); diff --git a/types/contracts/minter/config_response.d.ts b/types/contracts/minter/config_response.d.ts index 9f77a3485..d97f2b4f4 100644 --- a/types/contracts/minter/config_response.d.ts +++ b/types/contracts/minter/config_response.d.ts @@ -3,7 +3,6 @@ import { Addr, Coin, Expiration } from "./shared-types"; export interface ConfigResponse { admin: Addr base_token_uri: string -batch_mint_limit?: (number | null) num_tokens: number per_address_limit?: (number | null) sg721_address: Addr diff --git a/types/contracts/minter/execute_msg.d.ts b/types/contracts/minter/execute_msg.d.ts index bcbb35130..7dce5d43a 100644 --- a/types/contracts/minter/execute_msg.d.ts +++ b/types/contracts/minter/execute_msg.d.ts @@ -17,11 +17,6 @@ per_address_limit: number [k: string]: unknown } } | { -update_batch_mint_limit: { -batch_mint_limit: number -[k: string]: unknown -} -} | { mint_to: { recipient: Addr [k: string]: unknown @@ -32,9 +27,4 @@ recipient: Addr token_id: number [k: string]: unknown } -} | { -batch_mint: { -num_mints: number -[k: string]: unknown -} }) diff --git a/types/contracts/minter/instantiate_msg.d.ts b/types/contracts/minter/instantiate_msg.d.ts index 190df74e9..f69363f7f 100644 --- a/types/contracts/minter/instantiate_msg.d.ts +++ b/types/contracts/minter/instantiate_msg.d.ts @@ -9,7 +9,6 @@ export type Decimal = string export interface InstantiateMsg { base_token_uri: string -batch_mint_limit?: (number | null) num_tokens: number per_address_limit?: (number | null) sg721_code_id: number diff --git a/types/contracts/minter/query_msg.d.ts b/types/contracts/minter/query_msg.d.ts index ffd630c90..b8a9590a4 100644 --- a/types/contracts/minter/query_msg.d.ts +++ b/types/contracts/minter/query_msg.d.ts @@ -10,4 +10,8 @@ mintable_num_tokens: { start_time: { [k: string]: unknown } +} | { +mint_price: { +[k: string]: unknown +} }) diff --git a/types/contracts/minter/shared-types.d.ts b/types/contracts/minter/shared-types.d.ts index 494e391a0..813ce5aae 100644 --- a/types/contracts/minter/shared-types.d.ts +++ b/types/contracts/minter/shared-types.d.ts @@ -67,7 +67,6 @@ export interface Config { [k: string]: unknown; admin: Addr; base_token_uri: string; - batch_mint_limit?: (number | null); num_tokens: number; per_address_limit?: (number | null); sg721_code_id: number; diff --git a/types/contracts/sg721/query_msg.d.ts b/types/contracts/sg721/query_msg.d.ts index 698337ae2..3e8b68315 100644 --- a/types/contracts/sg721/query_msg.d.ts +++ b/types/contracts/sg721/query_msg.d.ts @@ -73,4 +73,8 @@ creator: { royalties: { [k: string]: unknown } +} | { +config: { +[k: string]: unknown +} }) diff --git a/types/contracts/whitelist/config.d.ts b/types/contracts/whitelist/config.d.ts index 1a862ebf0..87ce48c5b 100644 --- a/types/contracts/whitelist/config.d.ts +++ b/types/contracts/whitelist/config.d.ts @@ -15,6 +15,7 @@ export interface Config { admin: Addr end_time: Expiration num_members: number +per_address_limit: number start_time: Expiration unit_price: Coin [k: string]: unknown diff --git a/types/contracts/whitelist/execute_msg.d.ts b/types/contracts/whitelist/execute_msg.d.ts index 4427bdccc..fe2cd535f 100644 --- a/types/contracts/whitelist/execute_msg.d.ts +++ b/types/contracts/whitelist/execute_msg.d.ts @@ -6,6 +6,8 @@ update_start_time: Expiration update_end_time: Expiration } | { update_members: UpdateMembersMsg +} | { +update_per_address_limit: number }) export interface UpdateMembersMsg { diff --git a/types/contracts/whitelist/instantiate_msg.d.ts b/types/contracts/whitelist/instantiate_msg.d.ts index 4ca648976..2c4063d40 100644 --- a/types/contracts/whitelist/instantiate_msg.d.ts +++ b/types/contracts/whitelist/instantiate_msg.d.ts @@ -3,6 +3,7 @@ import { Coin, Expiration } from "./shared-types"; export interface InstantiateMsg { end_time: Expiration members: string[] +per_address_limit: number start_time: Expiration unit_price: Coin [k: string]: unknown diff --git a/types/contracts/whitelist/query_msg.d.ts b/types/contracts/whitelist/query_msg.d.ts index 85e1bb688..9ef8b9243 100644 --- a/types/contracts/whitelist/query_msg.d.ts +++ b/types/contracts/whitelist/query_msg.d.ts @@ -15,6 +15,10 @@ has_ended: { [k: string]: unknown } } | { +is_active: { +[k: string]: unknown +} +} | { members: { [k: string]: unknown } @@ -27,4 +31,8 @@ member: string unit_price: { [k: string]: unknown } +} | { +config: { +[k: string]: unknown +} })