use cosmwasm_std::{coins, Coin, Timestamp, Uint128};
use cw721::{Cw721QueryMsg, NumTokensResponse, OwnerOfResponse};
use cw_multi_test::{BankSudo, Executor, SudoMsg};
use open_edition_factory::state::ParamsExtension;
use sg_std::{GENESIS_MINT_START_TIME, NATIVE_DENOM};
use open_edition_minter::msg::{
ConfigResponse, EndTimeResponse, ExecuteMsg, MintCountResponse, MintPriceResponse,
MintableNumTokensResponse, QueryMsg, StartTimeResponse, TotalMintCountResponse,
};
use sg4::StatusResponse;
use crate::common_setup::setup_accounts_and_block::{coins_for_msg, setup_block_time};
use crate::common_setup::setup_minter::common::constants::{DEV_ADDRESS, MAX_TOKEN_LIMIT};
use crate::common_setup::setup_minter::open_edition_minter::minter_params::{
default_nft_data, init_msg,
};
use crate::common_setup::templates::open_edition_minter_custom_template;
const MINT_PRICE: u128 = 100_000_000;
fn check_mint_revenues_distribution(num_tokens: Option<u32>, end_minter_time: Option<Timestamp>) {
let params_extension = ParamsExtension {
max_token_limit: 10,
max_per_address_limit: 10,
airdrop_mint_fee_bps: 100,
airdrop_mint_price: Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::new(100_000_000u128),
},
dev_fee_address: DEV_ADDRESS.to_string(),
};
let per_address_limit_minter = Some(3);
let init_msg = init_msg(
default_nft_data(),
per_address_limit_minter,
None,
end_minter_time,
num_tokens,
None,
None,
);
let vt = open_edition_minter_custom_template(params_extension, init_msg).unwrap();
let (mut router, creator, buyer) = (vt.router, vt.accts.creator, vt.accts.buyer);
let minter_addr = vt.collection_response_vec[0].minter.clone().unwrap();
let collection_addr = vt.collection_response_vec[0].collection.clone().unwrap();
setup_block_time(&mut router, GENESIS_MINT_START_TIME + 101, None);
let initial_buyer_balances = router.wrap().query_all_balances(buyer.clone()).unwrap();
let initial_creator_balances = router.wrap().query_all_balances(creator.clone()).unwrap();
assert_eq!(
initial_creator_balances[0].amount,
Uint128::new(2_000_000_000)
);
let initial_dev_balances = router.wrap().query_all_balances(DEV_ADDRESS).unwrap();
assert_eq!(initial_dev_balances[0].amount, Uint128::new(2_000_000_000));
let query_start_time_msg: QueryMsg = QueryMsg::StartTime {};
let res: StartTimeResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_start_time_msg)
.unwrap();
assert_eq!(
res.start_time,
Timestamp::from_nanos(GENESIS_MINT_START_TIME + 100).to_string()
);
let query_end_time_msg: QueryMsg = QueryMsg::EndTime {};
let res: EndTimeResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_end_time_msg)
.unwrap();
if end_minter_time.is_some() {
assert_eq!(
res.end_time,
Some(Timestamp::from_nanos(GENESIS_MINT_START_TIME + 10_000).to_string())
);
} else {
assert_eq!(res.end_time, None);
}
let query_config_msg = QueryMsg::MintableNumTokens {};
let res: MintableNumTokensResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
if end_minter_time.is_some() {
assert_eq!(res.count, Some(MAX_TOKEN_LIMIT));
} else {
assert_eq!(res.count, Some(5));
}
let query_config_msg = QueryMsg::Config {};
let res: ConfigResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
if end_minter_time.is_some() {
assert_eq!(res.num_tokens, None);
assert_eq!(res.end_time, end_minter_time);
} else {
assert_eq!(res.num_tokens, Some(5));
assert_eq!(res.end_time, None);
}
let query_total_minted_msg: QueryMsg = QueryMsg::TotalMintCount {};
let res: TotalMintCountResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_total_minted_msg)
.unwrap();
assert_eq!(res.count, 0u32);
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
buyer.clone(),
minter_addr.clone(),
&mint_msg,
&coins(100u128, NATIVE_DENOM),
);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"IncorrectPaymentAmount 100ustars != 100000000ustars"
);
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
buyer.clone(),
minter_addr.clone(),
&mint_msg,
&coins(200_000_000u128, NATIVE_DENOM),
);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"IncorrectPaymentAmount 200000000ustars != 100000000ustars"
);
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(buyer.clone(), minter_addr.clone(), &mint_msg, &[]);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"IncorrectPaymentAmount 0ustars != 100000000ustars"
);
router
.sudo(SudoMsg::Bank({
BankSudo::Mint {
to_address: buyer.to_string(),
amount: coins(100_000u128, "invalid".to_string()),
}
}))
.map_err(|err| println!("{err:?}"))
.ok();
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
buyer.clone(),
minter_addr.clone(),
&mint_msg,
&coins(100u128, "invalid".to_string()),
);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Received unsupported denom 'invalid'"
);
for _i in 1..=2 {
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
buyer.clone(),
minter_addr.clone(),
&mint_msg,
&coins(MINT_PRICE, NATIVE_DENOM),
);
assert!(res.is_ok());
}
let buyer_balances = router.wrap().query_all_balances(buyer.clone()).unwrap();
assert_eq!(
buyer_balances[1].amount,
initial_buyer_balances[0].amount - Uint128::new(200_000_000u128)
);
let creator_balances = router.wrap().query_all_balances(creator.clone()).unwrap();
assert_eq!(
creator_balances[0].amount,
initial_creator_balances[0].amount + Uint128::new(200_000_000 - 20_000_000)
);
let dev_balances = router.wrap().query_all_balances(DEV_ADDRESS).unwrap();
assert_eq!(
dev_balances[0].amount,
initial_dev_balances[0].amount + Uint128::new(5_000_000 * 2)
);
let query_owner_msg = Cw721QueryMsg::OwnerOf {
token_id: String::from("2"),
include_expired: None,
};
let res: OwnerOfResponse = router
.wrap()
.query_wasm_smart(collection_addr.clone(), &query_owner_msg)
.unwrap();
assert_eq!(res.owner, buyer.to_string());
let num_tokens_msg = Cw721QueryMsg::NumTokens {};
let res: NumTokensResponse = router
.wrap()
.query_wasm_smart(collection_addr, &num_tokens_msg)
.unwrap();
assert_eq!(res.count, 2);
let query_config_msg = QueryMsg::StartTime {};
let res: StartTimeResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
assert_eq!(res.start_time, "1647032400.000000100");
let mint_to_msg = ExecuteMsg::MintTo {
recipient: buyer.to_string(),
};
let res = router.execute_contract(
creator.clone(),
minter_addr.clone(),
&mint_to_msg,
&[Coin {
amount: Uint128::from(100_000_000u128),
denom: NATIVE_DENOM.to_string(),
}],
);
assert!(res.is_ok());
let res: MintCountResponse = router
.wrap()
.query_wasm_smart(
minter_addr.clone(),
&QueryMsg::MintCount {
address: buyer.to_string(),
},
)
.unwrap();
assert_eq!(res.count, 2);
assert_eq!(res.address, buyer.to_string());
let query_config_msg = QueryMsg::Status {};
let res: StatusResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
assert!(!res.status.is_blocked);
let query_config_msg = QueryMsg::MintPrice {};
let res: MintPriceResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
assert_eq!(
res.airdrop_price,
Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::new(100_000_000)
}
);
assert_eq!(
res.current_price,
Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::new(100_000_000)
}
);
assert_eq!(
res.public_price,
Coin {
denom: NATIVE_DENOM.to_string(),
amount: Uint128::new(100_000_000)
}
);
let query_total_minted_msg: QueryMsg = QueryMsg::TotalMintCount {};
let res: TotalMintCountResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_total_minted_msg)
.unwrap();
assert_eq!(res.count, 3u32);
setup_block_time(&mut router, GENESIS_MINT_START_TIME + 1_000_000, None);
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
buyer.clone(),
minter_addr.clone(),
&mint_msg,
&coins(MINT_PRICE, NATIVE_DENOM),
);
if end_minter_time.is_some() {
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Minting has ended"
);
} else {
assert!(res.is_ok());
}
let exec_msg = ExecuteMsg::MintTo {
recipient: buyer.to_string(),
};
let res = router.execute_contract(buyer.clone(), minter_addr.clone(), &exec_msg, &[]);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Unauthorized: Sender is not an admin"
);
let exec_msg = ExecuteMsg::UpdatePerAddressLimit {
per_address_limit: 200,
};
let res = router.execute_contract(buyer.clone(), minter_addr.clone(), &exec_msg, &[]);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Unauthorized: Sender is not an admin"
);
let exec_msg = ExecuteMsg::UpdateStartTradingTime(Some(Timestamp::from_nanos(1)));
let res = router.execute_contract(buyer.clone(), minter_addr.clone(), &exec_msg, &[]);
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Unauthorized: Sender is not an admin"
);
let minter_balance = router
.wrap()
.query_all_balances(minter_addr.clone())
.unwrap();
assert_eq!(minter_balance.len(), 0);
let res = router.execute_contract(
creator.clone(),
minter_addr.clone(),
&mint_to_msg,
&coins_for_msg(Coin {
amount: Uint128::from(100_000_000u128),
denom: NATIVE_DENOM.to_string(),
}),
);
if end_minter_time.is_some() {
assert!(res.is_err());
} else {
assert!(res.is_ok());
}
let query_config_msg = QueryMsg::TotalMintCount {};
let res: TotalMintCountResponse = router
.wrap()
.query_wasm_smart(minter_addr.clone(), &query_config_msg)
.unwrap();
if end_minter_time.is_some() {
assert_eq!(res.count, 3);
} else {
assert_eq!(res.count, 5);
}
let mint_msg = ExecuteMsg::Mint {};
let res = router.execute_contract(
creator.clone(),
minter_addr.clone(),
&mint_msg,
&coins(MINT_PRICE, NATIVE_DENOM),
);
if end_minter_time.is_some() {
assert_eq!(
res.err().unwrap().source().unwrap().to_string(),
"Minting has ended"
);
} else {
assert_eq!(res.err().unwrap().source().unwrap().to_string(), "Sold out");
}
let purge_msg = ExecuteMsg::Purge {};
let res = router.execute_contract(creator, minter_addr.clone(), &purge_msg, &[]);
assert!(res.is_ok());
let res: MintCountResponse = router
.wrap()
.query_wasm_smart(
minter_addr,
&QueryMsg::MintCount {
address: buyer.to_string(),
},
)
.unwrap();
assert_eq!(res.count, 0);
}
#[test]
fn check_mint_revenues_distribution_with_end_time() {
check_mint_revenues_distribution(
None,
Some(Timestamp::from_nanos(GENESIS_MINT_START_TIME + 10_000)),
)
}
#[test]
fn check_mint_revenues_distribution_without_end_time() {
check_mint_revenues_distribution(Some(5u32), None)
}