From af040e53c10bd90251871565f979a445e44bb727 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Wed, 6 Mar 2024 17:32:11 +0200 Subject: [PATCH 01/17] feat: proxy endpoints for bond contract Refs: #77 --- src/bonding_proxy.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 30 +++++++++++++----------- wasm/src/lib.rs | 10 +++++--- 3 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 src/bonding_proxy.rs diff --git a/src/bonding_proxy.rs b/src/bonding_proxy.rs new file mode 100644 index 0000000..0548d46 --- /dev/null +++ b/src/bonding_proxy.rs @@ -0,0 +1,54 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +mod bonding_contract_proxy { + multiversx_sc::imports!(); + multiversx_sc::derive_imports!(); + + #[multiversx_sc::proxy] + pub trait BondingProxy { + #[view(getLockPeriodBondAmount)] + fn lock_period_bond_amount(&self, lock_period: u64); + + #[payable("*")] + #[endpoint(bond)] + fn bond( + &self, + original_caller: &ManagedAddress, + token_identifier: TokenIdentifier, + nonce: u64, + lock_period: u64, + ); + } +} + +#[multiversx_sc::module] +pub trait BondingContractProxyMethods: crate::storage::StorageModule { + #[proxy] + fn bonding_proxy(&self, sc_address: ManagedAddress) + -> bonding_contract_proxy::Proxy; + + #[endpoint] + fn get_bond_amount_for_lock_period(&self, lock_period: u64) -> BigUint { + let bonding_contract_address = self.bond_contract_address().get(); + self.bonding_proxy(bonding_contract_address) + .lock_period_bond_amount(lock_period) + .execute_on_dest_context::() + } + + #[endpoint] + fn send_bond( + &self, + original_caller: &ManagedAddress, + token_identifier: TokenIdentifier, + nonce: u64, + lock_period: u64, + payment: EgldOrEsdtTokenPayment, + ) { + let bonding_contract_address = self.bond_contract_address().get(); + self.bonding_proxy(bonding_contract_address) + .bond(original_caller, token_identifier, nonce, lock_period) + .with_egld_or_single_esdt_transfer(payment) + .execute_on_dest_context::<()>(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 6885417..81f82b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ use crate::{ storage::DataNftAttributes, }; +pub mod bonding_proxy; pub mod callbacks; pub mod collection_management; pub mod errors; @@ -20,6 +21,7 @@ pub mod nft_mint_utils; pub mod requirements; pub mod storage; pub mod views; + #[multiversx_sc::contract] pub trait DataNftMint: storage::StorageModule @@ -29,6 +31,7 @@ pub trait DataNftMint: + views::ViewsModule + callbacks::Callbacks + collection_management::CollectionManagement + + bonding_proxy::BondingContractProxyMethods { // When the smart contract is deployed or upgraded, minting is automatically paused, whitelisting is enabled and default values are set #[init] @@ -166,8 +169,13 @@ pub trait DataNftMint: let treasury_address = self.treasury_address().get(); + let bond_amount = self.get_bond_amount_for_lock_period(lock_period_sec); + if price >= BigUint::zero() { - // require that the payment is price + bondAmount ([TO DO] - implement proxy view for bondAmount from the bonding contract) + require!( + payment.amount >= &price + &bond_amount, + ERR_NOT_ENOUGH_FUNDS + ); self.send().direct( &treasury_address, @@ -177,6 +185,8 @@ pub trait DataNftMint: ); payment.amount -= &price; + } else { + require!(payment.amount == bond_amount, ERR_NOT_ENOUGH_FUNDS); } let one_token = BigUint::from(1u64); @@ -215,19 +225,13 @@ pub trait DataNftMint: &self.create_uris(media, metadata), ); - let mut contract_call: ContractCallNoPayment = ContractCallNoPayment::new( - self.bond_contract_address().get(), - ManagedBuffer::new_from_bytes(b"bond"), + self.send_bond( + &caller, + token_identifier.clone(), + nonce, + lock_period_sec, + payment, ); - contract_call.proxy_arg(&caller); - contract_call.proxy_arg(&token_identifier); - contract_call.proxy_arg(&nonce); - contract_call.proxy_arg(&lock_period_sec); - - contract_call - .with_egld_or_single_esdt_transfer(payment.clone()) - .with_gas_limit(100_000_000u64) - .execute_on_dest_context::<()>(); self.send() .direct_esdt(&caller, &token_identifier, nonce, &supply); diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index ef170ea..868a33c 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 42 +// Endpoints: 46 // Async Callback: 1 -// Total number of exported functions: 44 +// Total number of exported functions: 48 #![no_std] #![allow(internal_features)] @@ -25,8 +25,10 @@ multiversx_sc_wasm_adapter::endpoints! { setLocalRoles => set_local_roles mint => mint_token burn => burn_token + setTreasuryAddress => set_treasury_address setIsPaused => set_is_paused setWhiteListEnabled => set_whitelist_enabled + setAntiSpamTax => set_anti_spam_tax setWhiteListSpots => set_whitelist_spots removeWhiteListSpots => remove_whitelist_spots setMintTimeLimit => set_mint_time_limit @@ -37,8 +39,10 @@ multiversx_sc_wasm_adapter::endpoints! { setWithdrawalAddress => set_withdrawal_address withdraw => withdraw getTokenId => token_id + getTreasuryAddress => treasury_address getWithdrawalAddress => withdrawal_address getMintedTokens => minted_tokens + getAntiSpamTax => anti_spam_tax getIsPaused => is_paused getMaxRoyalties => max_royalties getMinRoyalties => min_royalties @@ -52,8 +56,8 @@ multiversx_sc_wasm_adapter::endpoints! { getFrozenCount => frozen_count isWhiteListEnabled => whitelist_enabled rolesAreSet => roles_are_set - getBondContractAddress => bond_contract_address getAdministrator => administrator + getBondContractAddress => bond_contract_address getUserDataOut => get_user_data_out pause => pause_collection unpause => unpause_collection From b6e2419bd4c528d021d16e32df9935b35eab7701 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:52:59 +0200 Subject: [PATCH 02/17] feat: require bond contract to be set Refs: #77 --- src/requirements.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/requirements.rs b/src/requirements.rs index ab00ca5..de5fdc3 100644 --- a/src/requirements.rs +++ b/src/requirements.rs @@ -32,6 +32,9 @@ pub trait RequirementsModule: crate::storage::StorageModule { if self.roles_are_set().is_empty() { is_mint_ready = false; } + if self.bond_contract_address().is_empty() { + is_mint_ready = false; + } require!(is_mint_ready, ERR_MINTING_AND_BURNING_NOT_ALLOWED); } From 23b15344a7d605bcfe2ea10a806e0a89d728f26b Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:54:16 +0200 Subject: [PATCH 03/17] chore: update dev dependencies to use bond contract Refs: #78 --- Cargo.lock | 595 ++++---- Cargo.toml | 4 + tests/rust_tests.rs | 3135 ------------------------------------------- wasm/src/lib.rs | 6 +- 4 files changed, 293 insertions(+), 3447 deletions(-) delete mode 100644 tests/rust_tests.rs diff --git a/Cargo.lock b/Cargo.lock index ff53d37..d00859f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,18 +29,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3a318f1f38d2418400f8209655bfd825785afd25aa30bb7ba6cc792e4596748" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys 0.52.0", ] @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.69" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "arrayvec" @@ -96,17 +96,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -130,9 +119,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bech32" @@ -148,7 +137,7 @@ checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", "rand 0.8.5", - "rand_core 0.6.3", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -182,18 +171,18 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "bstr" -version = "1.2.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -201,15 +190,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -219,9 +208,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -231,9 +220,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.11" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -241,9 +230,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -253,9 +242,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -265,9 +254,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -325,33 +314,57 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core-mx-life-bonding-sc" +version = "0.0.0" +source = "git+https://github.com/Itheum/core-mx-life-bonding-sc#b03c0aa9f324f4038cc56541c2a77bbbd0946c29" +dependencies = [ + "multiversx-sc", +] + [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -379,6 +392,7 @@ dependencies = [ name = "datanftmint" version = "2.0.0" dependencies = [ + "core-mx-life-bonding-sc", "multiversx-sc", "multiversx-sc-scenario", ] @@ -398,16 +412,16 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] @@ -428,9 +442,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "encoding_rs" @@ -511,42 +525,42 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", @@ -559,9 +573,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -580,13 +594,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -597,22 +611,22 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "globset" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax", ] [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -620,19 +634,13 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.3" @@ -647,18 +655,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.0" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -683,9 +682,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -694,9 +693,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -717,9 +716,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -732,7 +731,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -764,39 +763,28 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata", "same-file", - "thread_local", "walkdir", "winapi-util", ] [[package]] name = "indexmap" -version = "1.9.2" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -816,15 +804,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -846,15 +834,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -868,18 +856,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mime" @@ -889,18 +874,18 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.9" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", @@ -1020,7 +1005,7 @@ dependencies = [ "serde", "serde_json", "toml", - "wasmparser 0.121.2", + "wasmparser", "wasmprinter", "zip", ] @@ -1119,11 +1104,10 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] @@ -1142,36 +1126,36 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.0", + "hermit-abi", "libc", ] [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.61" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.2", "cfg-if", @@ -1201,9 +1185,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.97" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", @@ -1279,15 +1263,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" @@ -1338,7 +1322,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1358,7 +1342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1372,11 +1356,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.6", + "getrandom 0.2.12", ] [[package]] @@ -1394,7 +1378,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -1408,9 +1392,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1419,15 +1415,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64", "bytes", @@ -1447,9 +1443,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -1463,13 +1461,12 @@ dependencies = [ [[package]] name = "ruplacer" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1001b63b19333d7a462006c7d281a43ce5c1b3c44cd2a9696ab54b8e9aa7e388" +checksum = "58a26a1b15ff113d31d139357f7422708312978ed69cd5dd47e36d1b80b7eaf3" dependencies = [ "Inflector", "anyhow", - "atty", "clap", "colored", "ignore", @@ -1493,9 +1490,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.2", "errno", @@ -1504,11 +1501,20 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -1521,11 +1527,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1565,18 +1571,18 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -1585,11 +1591,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ - "indexmap 1.9.2", + "indexmap", "itoa", "ryu", "serde", @@ -1597,9 +1603,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", @@ -1608,9 +1614,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -1672,9 +1678,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "slab" @@ -1687,41 +1693,31 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.4.10" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -1734,6 +1730,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -1757,24 +1759,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", + "windows-sys 0.52.0", ] [[package]] @@ -1794,9 +1786,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -1806,7 +1798,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -1848,11 +1840,11 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ - "indexmap 2.1.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -1870,11 +1862,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" dependencies = [ - "indexmap 2.1.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -1908,27 +1900,27 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -1941,9 +1933,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "url" @@ -1976,12 +1968,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -2000,12 +1991,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2014,9 +1999,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2024,9 +2009,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -2039,9 +2024,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -2051,9 +2036,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2061,9 +2046,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -2074,19 +2059,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" - -[[package]] -name = "wasmparser" -version = "0.118.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" -dependencies = [ - "indexmap 2.1.0", - "semver", -] +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasmparser" @@ -2095,25 +2070,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.4.2", - "indexmap 2.1.0", + "indexmap", "semver", ] [[package]] name = "wasmprinter" -version = "0.2.75" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d027eb8294904fc715ac0870cebe6b0271e96b90605ee21511e7565c4ce568c" +checksum = "60e73986a6b7fdfedb7c5bf9e7eb71135486507c8fbc4c0c42cffcb6532988b7" dependencies = [ "anyhow", - "wasmparser 0.118.1", + "wasmparser", ] [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2137,9 +2112,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2165,7 +2140,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -2185,17 +2160,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -2206,9 +2181,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -2218,9 +2193,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -2230,9 +2205,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -2242,9 +2217,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -2254,9 +2229,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -2266,9 +2241,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -2278,15 +2253,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" -version = "0.5.24" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0383266b19108dfc6314a56047aa545a1b4d1be60e799b4dbdd407b56402704b" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index af9c8aa..44e3196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,7 @@ path = "src/lib.rs" version = "0.47.4" [dev-dependencies.multiversx-sc-scenario] version = "0.47.4" + + +[dev-dependencies] +core-mx-life-bonding-sc = {git = "https://github.com/Itheum/core-mx-life-bonding-sc"} diff --git a/tests/rust_tests.rs b/tests/rust_tests.rs deleted file mode 100644 index c6c7d2b..0000000 --- a/tests/rust_tests.rs +++ /dev/null @@ -1,3135 +0,0 @@ -use std::u8; - -use datanftmint::collection_management::CollectionManagement; -use datanftmint::errors::{ - ERR_FIELD_IS_EMPTY, ERR_MAX_ROYALTIES_TOO_HIGH, ERR_MIN_ROYALTIES_BIGGER_THAN_MAX_ROYALTIES, - ERR_TOO_MANY_CHARS, -}; -use datanftmint::nft_mint_utils::*; -use datanftmint::requirements::RequirementsModule; -use datanftmint::storage::*; -use datanftmint::views::{UserDataOut, ViewsModule}; -use datanftmint::*; -use multiversx_sc::contract_base::ContractBase; - -use multiversx_sc::types::{ManagedBuffer, ManagedVec, MultiValueEncoded}; -use multiversx_sc::{ - codec::Empty, - storage::mappers::StorageTokenWrapper, - types::{Address, EsdtLocalRole}, -}; - -use multiversx_sc_scenario::api::SingleTxApi; -use multiversx_sc_scenario::multiversx_chain_vm::tx_mock::TxContextRef; -use multiversx_sc_scenario::whitebox_legacy::{BlockchainStateWrapper, ContractObjWrapper}; -use multiversx_sc_scenario::*; - -pub const WASM_PATH: &'static str = "../output/datanftmint.wasm"; -pub const OWNER_EGLD_BALANCE: u128 = 100 * 10u128.pow(18u32); -pub const TOKEN_ID: &[u8] = b"ITHEUM-df6f26"; -pub const ANOTHER_TOKEN_ID: &[u8] = b"ANOTHER-123456"; -pub const COLLECTION_NAME: &[u8] = b"DATANFT-FT"; -pub const SFT_TICKER: &[u8] = b"DATANFTFT-1a2b3c"; -pub const SFT_NAME: &[u8] = b"DATA NFT-FT"; -pub const DATA_MARSHAL: &[u8] = b"https://DATA-MARSHAL-ENCRYPTED/marshal"; -pub const DATA_STREAM: &[u8] = b"https://DATA-STREAM-ECRYPTED/stream"; -pub const DATA_PREVIEW: &[u8] = b"https://DATA-STREAM-ECRYPTED/stream-preview"; -pub const MEDIA_URI: &[u8] = b"https://ipfs.io/ipfs/123456abcdef/media.json"; -pub const METADATA_URI: &[u8] = b"https://ipfs.io/ipfs/123456abcdef/metadata.json"; -pub const URL_WITH_SPACES: &[u8] = b"https://DATA-MARSHAL-ENCRYPTED/marshal with spaces"; -pub const URL_WITH_RETURN: &[u8] = b"https://DATA-MARSHAL-ENCRYPTED/marshal\r"; -pub const URL_WITHOUT_PROTOCOL: &[u8] = b"DATA-MARSHAL-ENCRYPTED/marshal/test/test/test"; -pub const USER_NFT_NAME: &[u8] = b"USER-NFT-NAME"; -pub const MINT_TIME_LIMIT: u64 = 15; -pub const ROLES: &[EsdtLocalRole] = &[ - EsdtLocalRole::NftCreate, - EsdtLocalRole::NftAddQuantity, - EsdtLocalRole::NftBurn, -]; - -struct ContractSetup -where - ContractObjBuilder: 'static + Copy + Fn() -> datanftmint::ContractObj, -{ - pub blockchain_wrapper: BlockchainStateWrapper, - pub owner_address: Address, - pub contract_wrapper: - ContractObjWrapper, ContractObjBuilder>, - pub first_user_address: Address, - pub second_user_address: Address, - pub treasury_address: Address, - pub withdrawal_address: Address, -} - -fn setup_contract( - cf_builder: ContractObjBuilder, -) -> ContractSetup -where - ContractObjBuilder: 'static + Copy + Fn() -> datanftmint::ContractObj, -{ - let rust_zero = rust_biguint!(0u64); - let mut blockchain_wrapper = BlockchainStateWrapper::new(); - let first_user_address = - blockchain_wrapper.create_user_account(&rust_biguint!(OWNER_EGLD_BALANCE / 10u128)); - let second_user_address = - blockchain_wrapper.create_user_account(&rust_biguint!(OWNER_EGLD_BALANCE / 100u128)); - let owner_address = blockchain_wrapper.create_user_account(&rust_biguint!(OWNER_EGLD_BALANCE)); - let withdrawal_address = blockchain_wrapper.create_user_account(&rust_biguint!(0u64)); - let treasury_address = - blockchain_wrapper.create_user_account(&rust_biguint!(OWNER_EGLD_BALANCE / 10u128)); - let cf_wrapper = blockchain_wrapper.create_sc_account( - &rust_zero, - Some(&owner_address), - cf_builder, - WASM_PATH, - ); - blockchain_wrapper.set_esdt_balance(&owner_address, TOKEN_ID, &rust_biguint!(5_000_000)); - blockchain_wrapper.set_esdt_balance( - &owner_address, - ANOTHER_TOKEN_ID, - &rust_biguint!(1_000_000), - ); - blockchain_wrapper.set_esdt_balance(&first_user_address, TOKEN_ID, &rust_biguint!(10_000)); - blockchain_wrapper.set_esdt_balance(&owner_address, ANOTHER_TOKEN_ID, &rust_biguint!(10_000)); - blockchain_wrapper.set_esdt_balance(&second_user_address, TOKEN_ID, &rust_biguint!(0)); - - blockchain_wrapper - .execute_tx(&owner_address, &cf_wrapper, &rust_zero, |sc| { - sc.init(); - }) - .assert_ok(); - - ContractSetup { - blockchain_wrapper, - owner_address, - first_user_address, - second_user_address, - treasury_address, - withdrawal_address, - contract_wrapper: cf_wrapper, - } -} - -#[test] // Tests whether the contract is deployed and initialized correctly after deployment. -fn deploy_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - setup - .blockchain_wrapper - .execute_tx( - &setup.owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.init(); - sc.set_royalties_limits(managed_biguint!(1u64), managed_biguint!(2u64)); - sc.set_max_supply(managed_biguint!(21u64)); - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - setup - .blockchain_wrapper - .execute_tx( - &setup.owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.init(); - assert_eq!(sc.min_royalties().get(), managed_biguint!(1u64)); - assert_eq!(sc.max_royalties().get(), managed_biguint!(2u64)); - assert_eq!(sc.max_supply().get(), managed_biguint!(21u64)); - assert_eq!(sc.whitelist_enabled().get(), true); - assert_eq!(sc.is_paused().get(), true); - }, - ) - .assert_ok(); -} - -#[test] //Tests owner setting a new admin - //Tests whether pause correct state after deployment - //Tests whether the owner can unpause the contract and pause again - //Tests whether the admin can unpause the contract -fn pause_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_administrator(managed_address!(first_user_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.is_paused().get(), true) - }) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.is_paused().get(), false) - }) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.is_paused().get(), true) - }) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.is_paused().get(), false) - }) - .assert_ok(); -} - -#[test] // Tests if the contract has whitelist enabled and is empty by default after deployment - // Tests if other values are set correctly after deployment - // Tests if the owner and administrator can change the max supply and royalties -fn value_setters_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let administrator_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.whitelist_enabled().get(), true) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.whitelist().len(), 0usize) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.min_royalties().get(), 0u64) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.max_royalties().get(), 8000u64) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.max_supply().get(), 20u64) - }) - .assert_ok(); - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_administrator(managed_address!(administrator_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_max_supply(managed_biguint!(100u64)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_royalties_limits(managed_biguint!(0u64), managed_biguint!(100u64)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_royalties_limits(managed_biguint!(10u64), managed_biguint!(1u64)); - }, - ) - .assert_user_error(ERR_MIN_ROYALTIES_BIGGER_THAN_MAX_ROYALTIES); - - b_wrapper - .execute_tx( - administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_royalties_limits(managed_biguint!(10u64), managed_biguint!(100000u64)); - }, - ) - .assert_user_error(ERR_MAX_ROYALTIES_TOO_HIGH); - - b_wrapper - .execute_tx( - administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_royalties_limits(managed_biguint!(1u64), managed_biguint!(10u64)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.set_treasury_address(managed_address!(treasury_address)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_max_supply(managed_biguint!(100u64)); - }, - ) - .assert_ok(); -} - -#[test] // Tests whether the owner can initialize the contract correctly. -fn setup_contract_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let treasury_address = &setup.treasury_address; - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_user_error("Issue cost is 0.05 eGLD"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_user_error("Contract was already initialized"); -} - -#[test] // Tests whether the owner and administrator can change the anti spam tax token - // Tests whether the owner and administrator can change the anti spam tax value -fn anti_spam_tax_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let administrator_address = &setup.first_user_address; - - b_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_administrator(managed_address!(administrator_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_anti_spam_tax( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - managed_biguint!(2_000_000), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_anti_spam_tax( - managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(2_000_000), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_anti_spam_tax( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - managed_biguint!(2_000_000), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &administrator_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_anti_spam_tax( - managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(2_000_000), - ) - }, - ) - .assert_ok(); -} - -#[test] -fn set_local_roles_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let treasury_address = &setup.treasury_address; - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_local_roles(); - }, - ) - .assert_user_error("Token not issued"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.roles_are_set().get(), false); - }) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.roles_are_set().get(), true); - }) - .assert_ok(); -} - -#[test] // Tests whether minting utilities for string creations works correctly. - // Tests whether the concatenation and sha256 hash encryption works correctly. -fn nft_mint_utils_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let treasury_address = &setup.treasury_address; - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let data_buffer = managed_buffer!(&[DATA_MARSHAL, DATA_STREAM].concat()); - let data_hash = sc.crypto().sha256(data_buffer).as_managed_buffer().clone(); - assert_eq!( - sc.create_hash_buffer( - &managed_buffer!(DATA_MARSHAL), - &managed_buffer!(DATA_STREAM) - ), - data_hash - ); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let uris = sc.create_uris(managed_buffer!(MEDIA_URI), managed_buffer!(METADATA_URI)); - let media_uri = uris.find(&managed_buffer!(MEDIA_URI)); - assert_eq!(media_uri, Some(0usize)); - }) - .assert_ok(); -} - -#[test] // Tests whether the requirements for minting are correctly checked. - // Tests all possible cases for requirements. -fn requirements_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let second_user_address = &setup.second_user_address; - let treasury_address = &setup.treasury_address; - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| { - sc.initialize_contract( - managed_buffer!(COLLECTION_NAME), - managed_buffer!(SFT_TICKER), - &managed_token_id_wrapped!(TOKEN_ID), - managed_biguint!(1_000_000), - MINT_TIME_LIMIT, - managed_address!(treasury_address), - ) - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.treasury_address().get(), - managed_address!(treasury_address) - ); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_token_issued(); - }) - .assert_user_error("Token not issued"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_ready_for_minting_and_burning(); - }) - .assert_error(4, "Minting and burning not allowed"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_ready_for_minting_and_burning(); - }) - .assert_error(4, "Minting and burning not allowed"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_token_issued(); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_ready_for_minting_and_burning(); - }) - .assert_error(4, "Minting and burning not allowed"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_ready_for_minting_and_burning(); - }) - .assert_user_error("Minting and burning not allowed"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.roles_are_set().set(false); - - assert_eq!(sc.roles_are_set().get(), false); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_ready_for_minting_and_burning(); - }) - .assert_user_error("Minting and burning not allowed"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.roles_are_set().set(true); - assert_eq!(sc.roles_are_set().get(), true); - - sc.require_ready_for_minting_and_burning(); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_is_privileged(&managed_address!(owner_address)) - }) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_administrator(managed_address!(first_user_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_max_supply(managed_biguint!(20)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &second_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_administrator(managed_address!(second_user_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &second_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_is_paused(true); - }, - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_is_privileged(&managed_address!(first_user_address)) - }) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_value_is_positive(&managed_biguint!(0u64)); - }) - .assert_error(4, "Value must be higher than zero"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_sft_is_valid(&managed_biguint!(90000u64), &managed_biguint!(2u64)); - }) - .assert_error(4, "Royalties are bigger than max royalties"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_sft_is_valid(&managed_biguint!(u8::MIN), &managed_biguint!(2u64)); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_sft_is_valid(&managed_biguint!(u8::MIN), &managed_biguint!(23u64)); - }) - .assert_error(4, "Max supply exceeded"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_sft_is_valid(&managed_biguint!(u8::MIN), &managed_biguint!(0u64)); - }) - .assert_error(4, "Supply must be higher than zero"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_minting_is_allowed(&managed_address!(first_user_address), 0u64); - }) - .assert_error(4, "You need to wait more time before minting again"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_minting_is_allowed(&managed_address!(first_user_address), 15u64); - }) - .assert_error(4, "You are not whitelisted"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_minting_is_allowed(&managed_address!(first_user_address), 15u64); - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_royalties_are_valid(&managed_biguint!(10u64), &managed_biguint!(1u64)); - }) - .assert_user_error(ERR_MIN_ROYALTIES_BIGGER_THAN_MAX_ROYALTIES); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_royalties_are_valid(&managed_biguint!(1u64), &managed_biguint!(10000u64)) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_royalties_are_valid(&managed_biguint!(1u64), &managed_biguint!(9900u64)) - }) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid(&managed_buffer!(b""), &managed_buffer!(b"")) - }) - .assert_user_error(ERR_FIELD_IS_EMPTY); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid( - &managed_buffer!(b""), - &managed_buffer!(b"RANDOM"), - ) - }) - .assert_user_error(ERR_FIELD_IS_EMPTY); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid( - &managed_buffer!(b"Random"), - &managed_buffer!(b""), - ) - }) - .assert_user_error(ERR_FIELD_IS_EMPTY); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid( - &managed_buffer!(&[1u8; 101]), - &managed_buffer!(&[1u8; 400]), - ) - }) - .assert_user_error(ERR_TOO_MANY_CHARS); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid( - &managed_buffer!(b"Random"), - &managed_buffer!(&[1u8; 401]), - ) - }) - .assert_user_error(ERR_TOO_MANY_CHARS); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_title_description_are_valid( - &managed_buffer!(b"Random"), - &managed_buffer!(&[1u8; 400]), - ) - }) - .assert_ok(); -} - -#[test] // Tests whether minting works correctly. - // Tests if the creator is in the NFT-FT attributes -fn mint_nft_ft_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [test] when deployed a smart contract is paused and token_id is empty so require_ready_for_minting_and_burning asserts - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2), - managed_biguint!(10), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Minting and burning not allowed"); - - // [setup] owner unpauses contract - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - // [test] require_sft_is_valid assert fails as supply is 0 - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(20), - managed_biguint!(0), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Supply must be higher than zero"); - - // [test] require_sft_is_valid assert fails as royalties exceed the max royalties - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(90000), - managed_biguint!(1), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Royalties are bigger than max royalties"); - - // @TODO DAVID: also test following assertions so we have complete test flow: "Royalties are smaller than min royalties", "Max supply exceeded" - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.min_royalties().set(&managed_biguint!(100u64)), - ) - .assert_ok(); - - // [test] require_sft_is_valid assert fails as royalties are smaller than min royalties - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(0u64), - managed_biguint!(1), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_user_error("Royalties are smaller than min royalties"); - - // [test] require_sft_is_valid assert fails as supply exceeds max supply - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(5000u64), - managed_biguint!(1000), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_user_error("Max supply exceeded"); - - // [test] require_minting_is_allowed assert fails as caller not whitelisted - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "You are not whitelisted"); - - // [setup] setting mint_time_limit to 15 mins (is it mins or sec or ms?).. i.e. u need to wait 15 mins to try again - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_mint_time_limit(15u64); - }, - ) - .assert_ok(); - - // [test] fails as user did not wait 15 mins to try (@TOCONFIRM - if last test reverted then last_mint_time should not be set right? so how does this fail?) - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "You need to wait more time before minting again"); - - // [setup] setting mint_time_limit to 0 mins (is it mins or sec or ms?).. i.e. u need to wait 0 mins to try again - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_mint_time_limit(0u64); - }, - ) - .assert_ok(); - - // [setup] setting set_whitelist_spots to caller so he is whitelisted - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - // [test] require_value_is_positive assert fails as user is setting egld_payment to 0 (should be the ITHEUM tax amount) - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Value must be higher than zero"); - - // [test] fails as tax payment is not sufficient (egld_payment value is less than anti_spam_tax(&payment.token_identifier).get()) - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(2u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Wrong amount of payment sent"); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(2u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(b""), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "Data Stream is empty"); - - // [setup] setting set_anti_spam_tax to 200 ITHEUM - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - // [setup] giving the minter contract special roles needed. (in actual contract this is done on async OK of initialize_contract.issue_semi_fungible) - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - // [test] minting will now succeed as it meets all criteria - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - // [test] as minting succeeded, minted_tokens should increment by 1 - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.minted_tokens().get(), 1u64); - }) - .assert_ok(); - // check if the payment token was transfered from the contract to the treasury address - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.blockchain() - .get_sc_balance(&managed_token_id_wrapped!(TOKEN_ID), 0), - managed_biguint!(0u64) - ) - }) - .assert_ok(); - // check if the data NFT-FT is not in the contract balance - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.blockchain() - .get_sc_balance(&managed_token_id_wrapped!(SFT_TICKER), 1), - managed_biguint!(0u64) - ) - }) - .assert_ok(); - - // [test] as minting succeeded, minted_per_address should increment by 1 - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.minted_per_address(&managed_address!(first_user_address)) - .get(), - 1u64 - ); - }) - .assert_ok(); - - // [setup] remove the user from whitelist so we can test re-mint prevention - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.remove_whitelist_spots(args); - }, - ) - .assert_ok(); - - // [test] mint another SFT but it will fail as user was removed from whitelist - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_error(4, "You are not whitelisted"); - - // [setup] whitelisting him again so we can test a remint - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - // [test] mint another SFT (with new links), it succeeds as the mint_time_limit was set to 0 above - let data_stream_2: &[u8] = b"https://DATA-STREAM-ECRYPTED/stream-2"; - let data_preview_2: &[u8] = b"https://DATA-STREAM-ECRYPTED/stream-preview"; - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(data_stream_2), - managed_buffer!(data_preview_2), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - // [test] as minting succeeded, minted_tokens should increment by 1 (1 -> 2) - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!(sc.minted_tokens().get(), 2u64); - }) - .assert_ok(); - - // [test] as minting succeeded, minted_per_address should increment by 1 (1 -> 2) - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.minted_per_address(&managed_address!(first_user_address)) - .get(), - 2u64 - ); - }) - .assert_ok(); - - // [test] test if the get_user_data_out view returns the correct final state view based on our tests above - b_wrapper - .execute_tx( - first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - let nonces = sc.frozen_sfts_per_address(&managed_address!(first_user_address)); - let mut frozen_nonces = ManagedVec::new(); - for item in nonces.iter() { - frozen_nonces.push(item); - } - let data_out = UserDataOut { - anti_spam_tax_value: sc - .anti_spam_tax(&managed_token_id_wrapped!(TOKEN_ID)) - .get(), - is_paused: sc.is_paused().get(), - max_royalties: sc.max_royalties().get(), - min_royalties: sc.min_royalties().get(), - max_supply: sc.max_supply().get(), - mint_time_limit: sc.mint_time_limit().get(), - last_mint_time: sc - .last_mint_time(&managed_address!(first_user_address)) - .get(), - whitelist_enabled: sc.whitelist_enabled().get(), - is_whitelisted: sc - .whitelist() - .contains(&managed_address!(first_user_address)), - minted_per_user: sc - .minted_per_address(&managed_address!(first_user_address)) - .get(), - total_minted: sc.minted_tokens().get(), - frozen: sc - .frozen_addresses_for_collection() - .contains(&managed_address!(first_user_address)), - frozen_nonces: frozen_nonces, - }; - assert_eq!( - sc.get_user_data_out( - &managed_address!(first_user_address), - &managed_token_id_wrapped!(TOKEN_ID) - ), - data_out - ); - }, - ) - .assert_ok(); - - // [test] test if DataNftAttributes of 1st (nonce) SFT minted above matches on-chain state (and if creator attr holds user address) - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(first_user_address), - &managed_token_id!(SFT_TICKER), - 1u64, - ); - let attributes = token_data.decode_attributes::>(); - - let test_attributes: DataNftAttributes = DataNftAttributes { - creation_time: attributes.creation_time, - creator: managed_address!(first_user_address), - data_marshal_url: managed_buffer!(DATA_MARSHAL), - data_preview_url: managed_buffer!(DATA_PREVIEW), - data_stream_url: managed_buffer!(DATA_STREAM), - title: managed_buffer!(USER_NFT_NAME), - description: managed_buffer!(USER_NFT_NAME), - }; - - let mut correct_uris: ManagedVec> = ManagedVec::new(); - - correct_uris.push(managed_buffer!(MEDIA_URI)); - correct_uris.push(managed_buffer!(METADATA_URI)); - - assert_eq!(correct_uris, token_data.uris); - - assert_eq!(test_attributes, attributes); - }) - .assert_ok(); - - // [test] test if DataNftAttributes of 2nd (nonce) SFT minted above matches on-chain state (and if creator attr holds user address) - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(first_user_address), - &managed_token_id!(SFT_TICKER), - 2u64, - ); - let attributes = token_data.decode_attributes::>(); - - let test_attributes: DataNftAttributes = DataNftAttributes { - creation_time: attributes.creation_time, - creator: managed_address!(first_user_address), - data_marshal_url: managed_buffer!(DATA_MARSHAL), - data_preview_url: managed_buffer!(data_preview_2), - data_stream_url: managed_buffer!(data_stream_2), - title: managed_buffer!(USER_NFT_NAME), - description: managed_buffer!(USER_NFT_NAME), - }; - - assert_eq!(test_attributes, attributes); - }) - .assert_ok() -} - -#[test] //Tests whether the whitelist functionality works as expected -fn whitelist_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let second_user_address = &setup.second_user_address; - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_administrator(managed_address!(second_user_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_whitelist_enabled(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &second_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - sc.set_whitelist_enabled(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let whitelist = MultiValueEncoded::new(); - sc.set_whitelist_spots(whitelist) - }) - .assert_user_error("Given whitelist is empty"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &second_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_user_error("Address already in whitelist"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - let whitelist = MultiValueEncoded::new(); - sc.remove_whitelist_spots(whitelist) - }) - .assert_user_error("Given whitelist is empty"); - - b_wrapper - .execute_tx( - &second_user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(first_user_address)); - sc.remove_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(first_user_address)); - sc.remove_whitelist_spots(args); - }, - ) - .assert_user_error("Address not in whitelist"); -} - -#[test] // Tests whether the burn functionality works as expected -fn burn_token_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] add caller to whitelist so he can mint - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - // [setup] add anti-spam tax or minting is prevented - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!("EGLD"), managed_biguint!(200)), - ) - .assert_ok(); - - // [setup] add collection id or minting is prevented - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - // [setup] give contract required sft roles - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - // [setup] unpause or minting is prevented - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - // [test] mint an SFT with 5 supply - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &first_user_address, - &setup.contract_wrapper, - &rust_biguint!(200u64), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(20), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - // [test] check if blockchain reports a balance of 5 for the newly minted SFT - b_wrapper.check_nft_balance( - first_user_address, - SFT_TICKER, - 1u64, - &rust_biguint!(5), - Option::<&Empty>::None, - ); - - // [test] burn just 1 of the supply - b_wrapper - .execute_esdt_transfer( - &first_user_address, - &setup.contract_wrapper, - SFT_TICKER, - 1u64, - &rust_biguint!(1), - |sc| { - sc.burn_token(); - }, - ) - .assert_ok(); - - // [test] check if blockchain reports a new balance of 4 - b_wrapper.check_nft_balance( - first_user_address, - SFT_TICKER, - 1u64, - &rust_biguint!(4), - Option::<&Empty>::None, - ); -} - -#[test] // Tests whether the url is valid -fn url_validation_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(URL_WITHOUT_PROTOCOL)) - }) - .assert_user_error("URL must start with https://"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(URL_WITH_SPACES)) - }) - .assert_user_error("URL contains invalid characters"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(URL_WITH_RETURN)) - }) - .assert_user_error("URL contains invalid characters"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(b"https://to.sm")); - }) - .assert_user_error("URL length is too small"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(&[ - SFT_TICKER, - DATA_MARSHAL, - DATA_STREAM, - MEDIA_URI, - DATA_STREAM, - MEDIA_URI, - DATA_STREAM, - MEDIA_URI, - SFT_TICKER, - DATA_MARSHAL, - DATA_STREAM, - MEDIA_URI, - DATA_STREAM, - MEDIA_URI, - DATA_STREAM, - MEDIA_URI - ] - .concat())) - }) - .assert_user_error("URL length is too big"); - - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - sc.require_url_is_valid(&managed_buffer!(MEDIA_URI)) - }) - .assert_ok(); -} - -#[test] // Tests whether an user cannot interact with functions that require privileges -fn privileges_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let user_address = &setup.first_user_address; - let second_user_address = &setup.second_user_address; - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - }, - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.set_whitelist_enabled(false), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(user_address)); - sc.remove_whitelist_spots(args); - }, - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.set_royalties_limits(managed_biguint!(200), managed_biguint!(200)), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.set_max_supply(managed_biguint!(200)), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.freeze_single_token_for_address(1u64, &managed_address!(second_user_address)), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.unfreeze_single_token_for_address(1u64, &managed_address!(second_user_address)), - ) - .assert_user_error("Address is not privileged"); - - b_wrapper - .execute_tx( - &user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.wipe_single_token_for_address(1u64, &managed_address!(second_user_address)), - ) - .assert_user_error("Address is not privileged"); -} - -#[test] // Freeze functions test -fn freeze_function_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - // [test] owner can freeze collection for address - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_addresses_for_collection() - .insert(managed_address!(first_user_address)); - sc.freeze_collection_for_address(&managed_address!(first_user_address)); - }, - ) - .assert_user_error("Address is in collection freeze list"); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_addresses_for_collection() - .remove(&managed_address!(first_user_address)); - sc.freeze_collection_for_address(&managed_address!(first_user_address)); - }, - ) - .assert_ok(); - - // [test] check that the address is stored in the frozen storage - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_addresses_for_collection() - .contains(&managed_address!(first_user_address)), - true - ); - }) - .assert_ok(); -} - -#[test] // Unfreeze function test -fn unfreeze_function_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.unfreeze_collection_for_address(&managed_address!(first_user_address)); - }, - ) - .assert_user_error("Address is not in collection freeze list"); - - // [test] freeze collection for address - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_addresses_for_collection() - .insert(managed_address!(first_user_address)); - }, - ) - .assert_ok(); - // [test] owner can unfreeze collection for address - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.unfreeze_collection_for_address(&managed_address!(first_user_address)); - }, - ) - .assert_ok(); - // [test] check that the address is removed from the frozen storage - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_addresses_for_collection() - .contains(&managed_address!(first_user_address)), - false - ); - }) - .assert_ok(); -} - -#[test] // Freeze sfts per address function test -fn freeze_sfts_per_address_function_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - // minted 2 tokens - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.minted_per_address(&managed_address!(first_user_address)) - .get(), - 2u64 - ); - }) - .assert_ok(); - // freeze the second token - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.freeze_single_token_for_address(1u64, &managed_address!(first_user_address)); - }, - ) - .assert_ok(); - // check if the storage is updated correctly - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .contains(&1u64), - true - ); - assert_eq!( - sc.frozen_count(&managed_address!(first_user_address)).get(), - 1usize - ); - }) - .assert_ok(); - - // for what reason (found out is not implemented) we get some error if we call two functions that implement esdt_system_sc_proxy (Recipient account is not a smart contract) - // We imitate the same behaviour as in the contract for freezing the second sft for the same address - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .insert(2u64); - }, - ) - .assert_ok(); - // setting the frozen count to 2 - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_count(&managed_address!(first_user_address)) - .set(2usize); - }, - ) - .assert_ok(); - // check if the sfts data is correct - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .len(), - 2usize - ); - assert_eq!( - sc.frozen_count(&managed_address!(first_user_address)).get(), - 2usize - ); - }) - .assert_ok(); -} - -#[test] // Unfreeze sfts per address function test -fn unfreeze_sfts_per_address_function_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - // minted 2 tokens - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.minted_per_address(&managed_address!(first_user_address)) - .get(), - 2u64 - ); - }) - .assert_ok(); - // freezing the tokens - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .insert(1u64); - }, - ) - .assert_ok(); - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .insert(2u64); - }, - ) - .assert_ok(); - // check if the token is added to the freeze_count array - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_count(&managed_address!(first_user_address)) - .set(2usize); - }, - ) - .assert_ok(); - // unfreeze the second token - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.unfreeze_single_token_for_address(2u64, &managed_address!(first_user_address)), - ) - .assert_ok(); - // check if the token is removed from the frozen_sfts_per_address array - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .contains(&1u64), - true - ); - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .len(), - 1usize - ); - assert_eq!( - sc.frozen_count(&managed_address!(first_user_address)).get(), - 1usize - ); - }) - .assert_ok(); -} - -#[test] // wipe sfts from address function test -fn wipe_function_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let b_wrapper = &mut setup.blockchain_wrapper; - let owner_address = &setup.owner_address; - let first_user_address = &setup.first_user_address; - let treasury_address = &setup.treasury_address; - - // [setup] owner sets the token ID (in real world, this is done via a callback after actual collection is minted) - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(5u64 * 10u64.pow(16u32)), - |sc| sc.token_id().set_token_id(managed_token_id!(SFT_TICKER)), - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_is_paused(false); - sc.roles_are_set().set(true); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.treasury_address() - .set(&managed_address!(treasury_address)); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| { - let mut args = MultiValueEncoded::new(); - args.push(managed_address!(&first_user_address)); - sc.set_whitelist_spots(args); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0), - |sc| sc.set_anti_spam_tax(managed_token_id_wrapped!(TOKEN_ID), managed_biguint!(200)), - ) - .assert_ok(); - - b_wrapper.set_esdt_local_roles(setup.contract_wrapper.address_ref(), SFT_TICKER, ROLES); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - - b_wrapper - .execute_esdt_transfer( - first_user_address, - &setup.contract_wrapper, - TOKEN_ID, - 0, - &rust_biguint!(200), - |sc| { - sc.mint_token( - managed_buffer!(USER_NFT_NAME), - managed_buffer!(MEDIA_URI), - managed_buffer!(METADATA_URI), - managed_buffer!(DATA_MARSHAL), - managed_buffer!(DATA_STREAM), - managed_buffer!(DATA_PREVIEW), - managed_biguint!(2000u64), - managed_biguint!(5), - managed_buffer!(USER_NFT_NAME), - managed_buffer!(USER_NFT_NAME), - ); - }, - ) - .assert_ok(); - // We minted 2 tokens, so we should have 2 in the minted count - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.minted_per_address(&managed_address!(first_user_address)) - .get(), - 2u64 - ); - }) - .assert_ok(); - // We push the minted tokens to the frozen storage - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .insert(1u64); - }, - ) - .assert_ok(); - - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .insert(2u64); - }, - ) - .assert_ok(); - // We check if the frozen storage has the correct values - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.frozen_count(&managed_address!(first_user_address)) - .set(2usize); - }, - ) - .assert_ok(); - // We check if the frozen storage has the correct values - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .len(), - 2usize - ); - assert_eq!( - sc.frozen_count(&managed_address!(first_user_address)).get(), - 2usize - ); - }) - .assert_ok(); - // We wipe the second token minted - b_wrapper - .execute_tx( - &owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| sc.wipe_single_token_for_address(2u64, &managed_address!(first_user_address)), - ) - .assert_ok(); - // We check if the frozen storage has the correct values after the wipe - b_wrapper - .execute_query(&setup.contract_wrapper, |sc| { - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .contains(&1u64), - true - ); - assert_eq!( - sc.frozen_sfts_per_address(&managed_address!(first_user_address)) - .len(), - 1usize - ); - assert_eq!( - sc.frozen_count(&managed_address!(first_user_address)).get(), - 1usize - ); - }) - .assert_ok(); -} - -#[test] // Tests the withdrawal endpoint -fn withdraw_test() { - let mut setup = setup_contract(datanftmint::contract_obj); - let owner_address = &setup.owner_address; - let withdrawal_address = &setup.withdrawal_address; - setup - .blockchain_wrapper - .execute_tx( - &setup.owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.init(); - sc.set_royalties_limits(managed_biguint!(1u64), managed_biguint!(2u64)); - sc.set_max_supply(managed_biguint!(21u64)); - sc.set_is_paused(false); - }, - ) - .assert_ok(); - - setup - .blockchain_wrapper - .execute_tx( - &setup.owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.init(); - assert_eq!(sc.min_royalties().get(), managed_biguint!(1u64)); - assert_eq!(sc.max_royalties().get(), managed_biguint!(2u64)); - assert_eq!(sc.max_supply().get(), managed_biguint!(21u64)); - assert_eq!(sc.whitelist_enabled().get(), true); - assert_eq!(sc.is_paused().get(), true); - }, - ) - .assert_ok(); - - setup.blockchain_wrapper.set_esdt_balance( - setup.contract_wrapper.address_ref(), - TOKEN_ID, - &rust_biguint!(10_000), - ); - setup.blockchain_wrapper.set_esdt_balance( - setup.contract_wrapper.address_ref(), - ANOTHER_TOKEN_ID, - &rust_biguint!(10_000), - ); - setup - .blockchain_wrapper - .set_egld_balance(setup.contract_wrapper.address_ref(), &rust_biguint!(20_000)); - - setup - .blockchain_wrapper - .execute_tx( - &setup.first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(TOKEN_ID), - 0u64, - managed_biguint!(10_000u64), - ); - }, - ) - .assert_user_error("Withdrawal address not set"); - - setup - .blockchain_wrapper - .execute_tx( - owner_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.set_withdrawal_address(managed_address!(withdrawal_address)); - }, - ) - .assert_ok(); - - setup - .blockchain_wrapper - .execute_tx( - &setup.first_user_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(TOKEN_ID), - 0u64, - managed_biguint!(10_000u64), - ); - }, - ) - .assert_user_error("Only withdrawal address can withdraw tokens"); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(TOKEN_ID), - 0u64, - managed_biguint!(12_000u64), - ); - }, - ) - .assert_user_error("Not enough funds"); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - 0u64, - managed_biguint!(12_000u64), - ); - }, - ) - .assert_user_error("Not enough funds"); - - setup.blockchain_wrapper.set_esdt_balance( - setup.contract_wrapper.address_ref(), - ANOTHER_TOKEN_ID, - &rust_biguint!(10_000), - ); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - 0u64, - managed_biguint!(12_000u64), - ); - }, - ) - .assert_user_error("Not enough funds"); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - 0u64, - managed_biguint!(12_000u64), - ); - }, - ) - .assert_user_error("Not enough funds"); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - 0u64, - managed_biguint!(0u64), - ); - }, - ) - .assert_user_error("Value must be higher than zero"); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(TOKEN_ID), - 0u64, - managed_biguint!(5_000u64), - ); - }, - ) - .assert_ok(); - - setup.blockchain_wrapper.check_esdt_balance( - &setup.contract_wrapper.address_ref(), - TOKEN_ID, - &rust_biguint!(5_000u64), - ); - setup.blockchain_wrapper.check_esdt_balance( - &setup.contract_wrapper.address_ref(), - ANOTHER_TOKEN_ID, - &rust_biguint!(10_000u64), - ); - setup.blockchain_wrapper.check_egld_balance( - &setup.contract_wrapper.address_ref(), - &rust_biguint!(20_000u64), - ); - - setup.blockchain_wrapper.check_esdt_balance( - &withdrawal_address, - TOKEN_ID, - &rust_biguint!(5_000u64), - ); - setup.blockchain_wrapper.check_esdt_balance( - &withdrawal_address, - ANOTHER_TOKEN_ID, - &rust_biguint!(0u64), - ); - setup - .blockchain_wrapper - .check_egld_balance(&withdrawal_address, &rust_biguint!(0u64)); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(TOKEN_ID), - 0u64, - managed_biguint!(5_000u64), - ); - }, - ) - .assert_ok(); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw( - managed_token_id_wrapped!(ANOTHER_TOKEN_ID), - 0u64, - managed_biguint!(10_000u64), - ); - }, - ) - .assert_ok(); - - setup - .blockchain_wrapper - .execute_tx( - withdrawal_address, - &setup.contract_wrapper, - &rust_biguint!(0u64), - |sc| { - sc.withdraw(managed_egld_token_id!(), 0u64, managed_biguint!(20_000u64)); - }, - ) - .assert_ok(); - - setup.blockchain_wrapper.check_esdt_balance( - &setup.contract_wrapper.address_ref(), - TOKEN_ID, - &rust_biguint!(0u64), - ); - setup.blockchain_wrapper.check_esdt_balance( - &setup.contract_wrapper.address_ref(), - ANOTHER_TOKEN_ID, - &rust_biguint!(0u64), - ); - setup - .blockchain_wrapper - .check_egld_balance(&setup.contract_wrapper.address_ref(), &rust_biguint!(0u64)); - - setup.blockchain_wrapper.check_esdt_balance( - &withdrawal_address, - TOKEN_ID, - &rust_biguint!(10_000u64), - ); - setup.blockchain_wrapper.check_esdt_balance( - &withdrawal_address, - ANOTHER_TOKEN_ID, - &rust_biguint!(10_000u64), - ); - setup - .blockchain_wrapper - .check_egld_balance(&withdrawal_address, &rust_biguint!(20_000u64)); -} diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 868a33c..0fc1b9a 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 46 +// Endpoints: 48 // Async Callback: 1 -// Total number of exported functions: 48 +// Total number of exported functions: 50 #![no_std] #![allow(internal_features)] @@ -66,6 +66,8 @@ multiversx_sc_wasm_adapter::endpoints! { freezeSingleNFT => freeze_single_token_for_address unFreezeSingleNFT => unfreeze_single_token_for_address wipeSingleNFT => wipe_single_token_for_address + get_bond_amount_for_lock_period => get_bond_amount_for_lock_period + send_bond => send_bond ) } From ab29efa44fe3540b702d67b7c72ee60f9b5588fa Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:54:47 +0200 Subject: [PATCH 04/17] test: contract ready feature tests Refs: #78 --- tests/unit_test.rs | 510 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 tests/unit_test.rs diff --git a/tests/unit_test.rs b/tests/unit_test.rs new file mode 100644 index 0000000..5ba0653 --- /dev/null +++ b/tests/unit_test.rs @@ -0,0 +1,510 @@ +use datanftmint::{requirements::RequirementsModule, storage::StorageModule as _, DataNftMint}; +use multiversx_sc::{storage::mappers::StorageTokenWrapper as _, types::BigUint}; +use multiversx_sc_scenario::{ + api::SingleTxApi, managed_address, managed_buffer, managed_token_id, + scenario_model::AddressValue, +}; + +use crate::minter_state::minter_state::ITHEUM_TOKEN_IDENTIFIER; + +mod endpoints; +mod minter_state; + +#[test] +fn minter_contract_ready_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.require_ready_for_minting_and_burning(); + }); + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.administrator().set(managed_address!( + &AddressValue::from("address:admin").to_address() + )); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.is_paused().set(false); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.is_paused().set(false); + minter_contract.administrator().set(managed_address!( + &AddressValue::from("address:admin").to_address() + )); + + minter_contract + .treasury_address() + .set(managed_address!( + &AddressValue::from("address:treasury").to_address() + )); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.is_paused().set(false); + minter_contract.administrator().set(managed_address!( + &AddressValue::from("address:admin").to_address() + )); + + minter_contract + .treasury_address() + .set(managed_address!( + &AddressValue::from("address:treasury").to_address() + )); + + minter_contract + .token_id() + .set_token_id(managed_token_id!(b"TOKEN-fb133")); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.is_paused().set(false); + minter_contract.administrator().set(managed_address!( + &AddressValue::from("address:admin").to_address() + )); + + minter_contract + .treasury_address() + .set(managed_address!( + &AddressValue::from("address:treasury").to_address() + )); + + minter_contract + .token_id() + .set_token_id(managed_token_id!(b"TOKEN-fb133")); + + minter_contract + .bond_contract_address() + .set(managed_address!( + &AddressValue::from("address:bond").to_address() + )); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + + minter_contract.is_paused().set(false); + minter_contract.administrator().set(managed_address!( + &AddressValue::from("address:admin").to_address() + )); + + minter_contract + .treasury_address() + .set(managed_address!( + &AddressValue::from("address:treasury").to_address() + )); + + minter_contract + .token_id() + .set_token_id(managed_token_id!(ITHEUM_TOKEN_IDENTIFIER)); + + minter_contract + .bond_contract_address() + .set(managed_address!( + &AddressValue::from("address:bond").to_address() + )); + + minter_contract.roles_are_set().set(true); + + minter_contract.require_ready_for_minting_and_burning(); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_withdrawal_address_is_set() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_withdrawal_address_is_set(); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract + .withdrawal_address() + .set(managed_address!( + &AddressValue::from("address:withdraw").to_address() + )); + + minter_contract.require_withdrawal_address_is_set(); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_minting_is_allowed_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.init(); + minter_contract.require_minting_is_allowed( + &managed_address!(&AddressValue::from("address:test").to_address()), + 0, + ); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + minter_contract + .last_mint_time(&managed_address!( + &AddressValue::from("address:test").to_address() + )) + .set(12); + + minter_contract.mint_time_limit().set(10); + + minter_contract.require_minting_is_allowed( + &managed_address!(&AddressValue::from("address:test").to_address()), + 11, + ); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + minter_contract + .last_mint_time(&managed_address!( + &AddressValue::from("address:test").to_address() + )) + .set(12); + + minter_contract.mint_time_limit().set(10); + + minter_contract.require_minting_is_allowed( + &managed_address!(&AddressValue::from("address:test").to_address()), + 23, + ); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + minter_contract + .last_mint_time(&managed_address!( + &AddressValue::from("address:test").to_address() + )) + .set(12); + + minter_contract.mint_time_limit().set(10); + + minter_contract.whitelist_enabled().set(false); + + minter_contract.require_minting_is_allowed( + &managed_address!(&AddressValue::from("address:test").to_address()), + 23, + ); + }); + + assert_eq!(result.is_ok(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.init(); + minter_contract + .last_mint_time(&managed_address!( + &AddressValue::from("address:test").to_address() + )) + .set(12); + + minter_contract.mint_time_limit().set(10); + + minter_contract.whitelist_enabled().set(true); + + minter_contract.whitelist().insert(managed_address!( + &AddressValue::from("address:test").to_address() + )); + + minter_contract.require_minting_is_allowed( + &managed_address!(&AddressValue::from("address:test").to_address()), + 23, + ); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_value_is_positive_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_value_is_positive(&BigUint::zero()); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_value_is_positive(&BigUint::from(1u64)); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_sft_is_valid_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_sft_is_valid(&BigUint::zero(), &BigUint::zero()); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.max_royalties().set(BigUint::from(100u64)); + minter_contract.min_royalties().set(BigUint::from(10u64)); + minter_contract.max_supply().set(BigUint::from(1000u64)); + + minter_contract.require_sft_is_valid(&BigUint::from(100u64), &BigUint::from(1000u64)); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_title_description_are_valid_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract + .require_title_description_are_valid(&managed_buffer!(b""), &managed_buffer!(b"")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract + .require_title_description_are_valid(&managed_buffer!(b"Title"), &managed_buffer!(b"")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_title_description_are_valid( + &managed_buffer!(b""), + &managed_buffer!(b"Description"), + ); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_title_description_are_valid( + &managed_buffer!(b"Title"), + &managed_buffer!(b"Description"), + ); + }); + + assert_eq!(result.is_ok(), true); + + let result = std::panic::catch_unwind(|| { + minter_contract.require_title_description_are_valid( + &managed_buffer!(&[1u8; 101]), + &managed_buffer!(&[1u8; 400]), + ); + }); + + assert_eq!(result.is_err(), true); + + let result = std::panic::catch_unwind(|| { + minter_contract.require_title_description_are_valid( + &managed_buffer!(&[1u8; 100]), + &managed_buffer!(&[1u8; 401]), + ); + }); + + assert_eq!(result.is_err(), true); + + let result = std::panic::catch_unwind(|| { + minter_contract.require_title_description_are_valid( + &managed_buffer!(&[1u8; 100]), + &managed_buffer!(&[1u8; 400]), + ); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_url_is_valid_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"http://")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"https://")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"https://test.com/test/test ")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"https://test.com/test/test\r\n")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_valid(&managed_buffer!(b"https://test.com/test/test")); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_url_is_adequate_length_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_adequate_length(&managed_buffer!(b"")); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_adequate_length(&managed_buffer!(&[1u8; 401])); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_adequate_length(&managed_buffer!(&[1u8; 400])); + }); + + assert_eq!(result.is_ok(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_url_is_adequate_length(&managed_buffer!(&[1u8; 15])); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_royalties_are_valid_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract.require_royalties_are_valid(&BigUint::from(100u64), &BigUint::from(10u64)); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract.require_royalties_are_valid(&BigUint::from(10u64), &BigUint::from(100u64)); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_token_issued_test() { + let minter_conttract = datanftmint::contract_obj::(); + + let result = std::panic::catch_unwind(|| { + minter_conttract.require_token_issued(); + }); + + assert_eq!(result.is_err(), true); + + let result = std::panic::catch_unwind(|| { + minter_conttract + .token_id() + .set_token_id(managed_token_id!(ITHEUM_TOKEN_IDENTIFIER)); + + minter_conttract.require_token_issued(); + }); + + assert_eq!(result.is_ok(), true); +} + +#[test] +fn require_is_withdrawal_address_test() { + let minter_contract = datanftmint::contract_obj::(); + + let mut result = std::panic::catch_unwind(|| { + minter_contract + .withdrawal_address() + .set(managed_address!( + &AddressValue::from("address:withdraw").to_address() + )); + + minter_contract + .require_is_withdrawal_address(&managed_address!( + &AddressValue::from("address:test").to_address() + )); + }); + + assert_eq!(result.is_err(), true); + + result = std::panic::catch_unwind(|| { + minter_contract + .withdrawal_address() + .set(managed_address!( + &AddressValue::from("address:withdraw").to_address() + )); + + minter_contract.require_is_withdrawal_address(&managed_address!(&AddressValue::from( + "address:withdraw" + ) + .to_address())); + }); + + assert_eq!(result.is_ok(), true); +} From b1acca46b6dfe29cb8ab65728cbe0e18df855bc0 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:55:33 +0200 Subject: [PATCH 05/17] test: minter state interface for integration test Refs: #78 --- tests/minter_state/minter_state.rs | 819 +++++++++++++++++++++++++++++ tests/minter_state/mod.rs | 1 + 2 files changed, 820 insertions(+) create mode 100644 tests/minter_state/minter_state.rs create mode 100644 tests/minter_state/mod.rs diff --git a/tests/minter_state/minter_state.rs b/tests/minter_state/minter_state.rs new file mode 100644 index 0000000..ed70780 --- /dev/null +++ b/tests/minter_state/minter_state.rs @@ -0,0 +1,819 @@ +use core_mx_life_bonding_sc::{admin::ProxyTrait as _, config::ProxyTrait as _, ProxyTrait as _}; +use datanftmint::{collection_management::ProxyTrait as _, ProxyTrait as _}; +use multiversx_sc::{ + codec::multi_types::MultiValue2, + types::{Address, MultiValueEncoded}, +}; +use multiversx_sc_scenario::{ + api::StaticApi, + managed_address, managed_biguint, managed_token_id, managed_token_id_wrapped, + scenario_model::{Account, AddressValue, ScCallStep, ScDeployStep, SetStateStep, TxExpect}, + ContractInfo, ScenarioWorld, +}; + +pub const BONDING_CONTRACT_PATH: &str = "mxsc:output/core_mx_life_bonding_sc.mxsc.json"; + +pub const MINTER_CONTRACT_PATH: &str = "mxsc:output/datanftmint.mxsc.json"; +pub const MINTER_CONTRACT_ADDRESS_EXPR: &str = "sc:datanftmint"; + +pub const MINTER_OWNER_ADDRESS_EXPR: &str = "address:minter-owner"; +pub const MINTER_ADMIN_ADDRESS_EXPR: &str = "address:minter-admin"; + +pub const BONDING_OWNER_ADDRESS_EXPR: &str = "address:bonding-owner"; +pub const BONDING_ADMIN_ADDRESS_EXPR: &str = "address:bonding-admin"; + +pub const BONDING_CONTRACT_ADDRESS_EXPR: &str = "sc:bond_contract"; + +pub const ITHEUM_TOKEN_IDENTIFIER_EXPR: &str = "str:ITHEUM-fce905"; +pub const ITHEUM_TOKEN_IDENTIFIER: &[u8] = b"ITHEUM-fce905"; + +pub const ANOTHER_TOKEN_IDENTIFIER_EXPR: &str = "str:ANOTHER-fce905"; +pub const ANOTHER_TOKEN_IDENTIFIER: &[u8] = b"ANOTHER-fce905"; + +pub const DATA_NFT_IDENTIFIER_EXPR: &str = "str:DATANFT-12345"; +pub const DATA_NFT_IDENTIFIER: &[u8] = b"DATANFT-12345"; + +pub const COLLECTION_NAME: &str = "DATANFT-FT"; + +pub const FIRST_USER_ADDRESS_EXPR: &str = "address:first_user"; +pub const SECOND_USER_ADDRESS_EXPR: &str = "address:second_user"; +pub const THIRD_USER_ADDRESS_EXPR: &str = "address:third_user"; + +pub const TREAASURY_ADDRESS_EXPR: &str = "address:treasury"; + +pub const WITHDRAWAL_ADDRESS_EXPR: &str = "address:withdrawal"; + +type MinterContract = ContractInfo>; +type BondContract = ContractInfo>; + +pub fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + blockchain.set_current_dir_from_workspace(""); + + blockchain.register_contract(MINTER_CONTRACT_PATH, datanftmint::ContractBuilder); + + blockchain.register_contract( + BONDING_CONTRACT_PATH, + core_mx_life_bonding_sc::ContractBuilder, + ); + + blockchain +} + +pub struct ContractsState { + pub world: ScenarioWorld, + pub minter_contract: MinterContract, + pub bond_contract: BondContract, + pub admin: Address, + pub first_user: Address, + pub second_user: Address, + pub third_user: Address, + pub treasury: Address, +} + +impl ContractsState { + pub fn new() -> Self { + let mut world = world(); + + world.set_state_step( + SetStateStep::new() + .put_account( + MINTER_OWNER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("20000000000000000000") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "1_000"), + ) + .new_address(MINTER_OWNER_ADDRESS_EXPR, 1, MINTER_CONTRACT_ADDRESS_EXPR) + .put_account( + MINTER_ADMIN_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("1_000") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "1_000"), + ) + .put_account( + BONDING_OWNER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("1_000") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "1_000"), + ) + .new_address(BONDING_OWNER_ADDRESS_EXPR, 1, BONDING_CONTRACT_ADDRESS_EXPR) + .put_account( + BONDING_ADMIN_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("1_000") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "1_000"), + ) + .put_account( + FIRST_USER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("100") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "200") + .esdt_balance(ANOTHER_TOKEN_IDENTIFIER_EXPR, "5"), + ) + .put_account( + SECOND_USER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("100") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "200"), + ) + .put_account( + THIRD_USER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .balance("100") + .esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "200"), + ) + .put_account(WITHDRAWAL_ADDRESS_EXPR, Account::new().nonce(1)) + .put_account(TREAASURY_ADDRESS_EXPR, Account::new().nonce(1)), + ); + + let minter_contract = MinterContract::new(MINTER_CONTRACT_ADDRESS_EXPR); + let bond_contract = BondContract::new(BONDING_CONTRACT_ADDRESS_EXPR); + + let admin = AddressValue::from(MINTER_ADMIN_ADDRESS_EXPR).to_address(); + let first_user = AddressValue::from(FIRST_USER_ADDRESS_EXPR).to_address(); + let second_user = AddressValue::from(SECOND_USER_ADDRESS_EXPR).to_address(); + let third_user = AddressValue::from(THIRD_USER_ADDRESS_EXPR).to_address(); + let treasury = AddressValue::from(TREAASURY_ADDRESS_EXPR).to_address(); + + Self { + world, + minter_contract, + bond_contract, + admin, + first_user, + second_user, + third_user, + treasury, + } + } + + //minter setup + pub fn deploy_minter(&mut self) -> &mut Self { + let minter_code = self.world.code_expression(MINTER_CONTRACT_PATH); + + self.world.sc_deploy( + ScDeployStep::new() + .from(MINTER_OWNER_ADDRESS_EXPR) + .code(minter_code) + .call(self.minter_contract.init()), + ); + self + } + + pub fn minter_freeze_single_nft( + &mut self, + caller: &str, + nonce: u64, + address: &Address, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .freeze_single_token_for_address(nonce, managed_address!(address)), + ) + .expect(TxExpect::ok()), + ); + self + } + + pub fn minter_unfreeze_single_nft( + &mut self, + caller: &str, + nonce: u64, + address: &Address, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .unfreeze_single_token_for_address(nonce, managed_address!(address)), + ) + .expect(TxExpect::ok()), + ); + self + } + + pub fn minter_wipe_single_nft( + &mut self, + caller: &str, + nonce: u64, + address: &Address, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .wipe_single_token_for_address(nonce, managed_address!(address)), + ) + .expect(TxExpect::ok()), + ); + self + } + + pub fn minter_freeze_collection_for_address( + &mut self, + caller: &str, + address: &Address, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .freeze_collection_for_address(managed_address!(address)), + ) + .expect(TxExpect::ok()), + ); + self + } + + pub fn minter_unfreeze_collection_for_address( + &mut self, + caller: &str, + address: &Address, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .unfreeze_collection_for_address(managed_address!(address)), + ) + .expect(TxExpect::ok()), + ); + self + } + + pub fn minter_set_administarator( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_administrator(address)) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_treasury_address( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_treasury_address(address)) + .expect(tx_expect), + ); + self + } + + pub fn pause_minter_contract(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_is_paused(true)) + .expect(tx_expect), + ); + self + } + + pub fn unpause_minter_contract(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_is_paused(false)) + .expect(tx_expect), + ); + self + } + + pub fn minter_enable_whitelist(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_whitelist_enabled(true)) + .expect(tx_expect), + ); + self + } + + pub fn minter_disable_whitelist( + &mut self, + caller: &str, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_whitelist_enabled(false)) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_royalties_limits( + &mut self, + caller: &str, + min_royalties: u64, + max_royalties: u64, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_royalties_limits( + managed_biguint!(min_royalties), + managed_biguint!(max_royalties), + )) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_max_supply( + &mut self, + caller: &str, + max_supply: u64, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .set_max_supply(managed_biguint!(max_supply)), + ) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_anti_spam_tax_token_and_amount( + &mut self, + caller: &str, + token_identifier: &[u8], + amount: u64, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.minter_contract + .set_anti_spam_tax(managed_token_id_wrapped!(token_identifier), amount), + ) + .expect(tx_expect), + ); + self + } + + pub fn minter_add_to_whitelist( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + let mut multivalue = MultiValueEncoded::new(); + multivalue.push(managed_address!(&address)); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_whitelist_spots(multivalue)) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_bond_contract_address( + &mut self, + caller: &str, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + let bond_address = self.bond_contract.address.clone().into_option().unwrap(); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_bond_contract_address(bond_address)) + .expect(tx_expect), + ); + self + } + + pub fn minter_remove_from_whitelist( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + let mut multivalue = MultiValueEncoded::new(); + + multivalue.push(managed_address!(&address)); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.remove_whitelist_spots(multivalue)) + .expect(tx_expect), + ); + self + } + + pub fn minter_set_mint_time_limit( + &mut self, + caller: &str, + mint_time_limit: u64, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_mint_time_limit(mint_time_limit)) + .expect(tx_expect), + ); + self + } + + pub fn set_withdrawal_address( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_withdrawal_address(address)) + .expect(tx_expect), + ); + self + } + + pub fn minter_withdraw( + &mut self, + caller: &str, + token_identifier: &[u8], + nonce: u64, + amount: u64, + expect: Option, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.withdraw( + managed_token_id_wrapped!(token_identifier), + nonce, + managed_biguint!(amount), + )) + .expect(expect.unwrap_or(TxExpect::ok())), + ); + self + } + + pub fn minter_burn( + &mut self, + caller: &str, + token_identifier: &[u8], + nonce: u64, + amount: u64, + expect: Option, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .esdt_transfer(token_identifier, nonce, amount) + .call(self.minter_contract.burn_token()) + .expect(expect.unwrap_or(TxExpect::ok())), + ); + self + } + + pub fn minter_mint( + &mut self, + caller: &str, + name: &str, + media: &str, + medatada: &str, + data_marshal: &str, + data_stream: &str, + data_preview: &str, + royalties: u64, + supply: u64, + title: &str, + description: &str, + lock_period: u64, + payment_token_identifier: &[u8], + payment_token_nonce: u64, + payment_amount: u64, + expect: Option, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .esdt_transfer( + payment_token_identifier, + payment_token_nonce, + payment_amount, + ) + .call(self.minter_contract.mint_token( + name, + media, + medatada, + data_marshal, + data_stream, + data_preview, + managed_biguint!(royalties), + managed_biguint!(supply), + title, + description, + lock_period, + )) + .expect(expect.unwrap_or(TxExpect::ok())), + ); + self + } + + pub fn minter_set_local_roles(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.minter_contract.set_local_roles()) + .expect(tx_expect), + ); + self + } + + pub fn minter_initialize_contract( + &mut self, + caller: &str, + collection_name: &str, + token_ticker: &str, + anti_spam_tax_token: &[u8], + anti_spam_tax_value: u64, + mint_time_limit: u64, + treasury_address: Address, + amount: Option, + expect: Option, + ) -> &mut Self { + self.world.sc_call( + ScCallStep::new() + .from(caller) + .egld_value(amount.unwrap_or(50000000000000000)) + .call(self.minter_contract.initialize_contract( + collection_name, + token_ticker, + managed_token_id_wrapped!(anti_spam_tax_token), + managed_biguint!(anti_spam_tax_value), + mint_time_limit, + treasury_address, + )) + .expect(expect.unwrap_or(TxExpect::ok())), + ); + + self + } + + pub fn mock_minter_initialized( + &mut self, + anti_spam_tax_token: &[u8], + anti_spam_tax_value: u64, + mint_time_limit: u64, + ) -> &mut Self { + let admin = self.admin.clone(); + let treasury_address = self.treasury.clone(); + let minter_code = self.world.code_expression(MINTER_CONTRACT_PATH); + + let mut acc = Account::new() + .esdt_roles( + DATA_NFT_IDENTIFIER_EXPR, + vec![ + "ESDTRoleNFTCreate".to_string(), + "ESDTRoleNFTBurn".to_string(), + ], + ) + .code(minter_code); + + acc.storage.insert( + b"sft_token_id".to_vec().into(), + DATA_NFT_IDENTIFIER.to_vec().into(), + ); + + acc.storage + .insert(b"roles_are_set".to_vec().into(), b"1".to_vec().into()); + + acc.owner = Option::Some(AddressValue::from(MINTER_OWNER_ADDRESS_EXPR)); + self.world.set_state_step( + SetStateStep::new() + .new_token_identifier(DATA_NFT_IDENTIFIER_EXPR) + .put_account(MINTER_CONTRACT_ADDRESS_EXPR, acc), + ); + + self.minter_enable_whitelist(MINTER_OWNER_ADDRESS_EXPR, None); + self.minter_set_max_supply(MINTER_OWNER_ADDRESS_EXPR, 20u64, None); + self.minter_set_royalties_limits(MINTER_OWNER_ADDRESS_EXPR, 0u64, 8000u64, None); + self.minter_set_administarator(MINTER_OWNER_ADDRESS_EXPR, admin, None); + self.minter_set_bond_contract_address(MINTER_OWNER_ADDRESS_EXPR, None); + self.minter_set_treasury_address(MINTER_OWNER_ADDRESS_EXPR, treasury_address, None); + self.minter_set_anti_spam_tax_token_and_amount( + MINTER_OWNER_ADDRESS_EXPR, + anti_spam_tax_token, + anti_spam_tax_value, + None, + ); + self.minter_set_mint_time_limit(MINTER_OWNER_ADDRESS_EXPR, mint_time_limit, None); + self.minter_set_local_roles(MINTER_OWNER_ADDRESS_EXPR, None); + self + } + + pub fn minter_upgrade(&mut self) -> &mut Self { + let minter_code = self.world.code_expression(MINTER_CONTRACT_PATH); + self.world.sc_call( + ScCallStep::new() + .from(MINTER_OWNER_ADDRESS_EXPR) + .to(MINTER_CONTRACT_ADDRESS_EXPR) + .function("upgradeContract") + .argument(&minter_code) + .argument("0x0502") // codeMetadata + .expect(TxExpect::ok()), + ); + self + } + + // bonding setup + pub fn deploy_bonding(&mut self) -> &mut Self { + let bonding_code = self.world.code_expression(BONDING_CONTRACT_PATH); + + self.world.sc_deploy( + ScDeployStep::new() + .from(BONDING_OWNER_ADDRESS_EXPR) + .code(bonding_code) + .call(self.bond_contract.init()), + ); + self + } + + pub fn bond_set_administrator( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.bond_contract + .set_administrator(managed_address!(&address)), + ) + .expect(tx_expect), + ); + self + } + + pub fn bond_set_accepted_caller( + &mut self, + caller: &str, + address: Address, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + let mut arg = MultiValueEncoded::new(); + + arg.push(managed_address!(&address)); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.bond_contract.set_accepted_callers(arg)) + .expect(tx_expect), + ); + self + } + + pub fn bond_set_bond_token( + &mut self, + caller: &str, + token_identifier: &[u8], + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call( + self.bond_contract + .set_bond_token(managed_token_id!(token_identifier)), + ) + .expect(tx_expect), + ); + self + } + + pub fn bond_set_lock_period_and_bond( + &mut self, + caller: &str, + lock_period: u64, + bond: u64, + expect: Option, + ) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + let mut arg = MultiValueEncoded::new(); + arg.push(MultiValue2((lock_period, managed_biguint!(bond)))); + + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.bond_contract.set_lock_periods_with_bonds(arg)) + .expect(tx_expect), + ); + self + } + + pub fn bond_pause_contract(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.bond_contract.set_contract_state_inactive()) + .expect(tx_expect), + ); + self + } + + pub fn bond_unpause_contract(&mut self, caller: &str, expect: Option) -> &mut Self { + let tx_expect = expect.unwrap_or(TxExpect::ok()); + self.world.sc_call( + ScCallStep::new() + .from(caller) + .call(self.bond_contract.set_contract_state_active()) + .expect(tx_expect), + ); + self + } + + pub fn bond_contract_default_deploy_and_set( + &mut self, + lock_period: u64, + bond_amount: u64, + ) -> &mut Self { + let admin = self.admin.clone(); + self.deploy_bonding() + .bond_set_administrator(BONDING_OWNER_ADDRESS_EXPR, admin.clone(), None) + .bond_set_accepted_caller( + BONDING_OWNER_ADDRESS_EXPR, + AddressValue::from(MINTER_CONTRACT_ADDRESS_EXPR).to_address(), + None, + ) + .bond_set_bond_token(BONDING_OWNER_ADDRESS_EXPR, ITHEUM_TOKEN_IDENTIFIER, None) + .bond_set_lock_period_and_bond( + BONDING_OWNER_ADDRESS_EXPR, + lock_period, + bond_amount, + None, + ) + .bond_unpause_contract(BONDING_OWNER_ADDRESS_EXPR, None); + + self + } +} diff --git a/tests/minter_state/mod.rs b/tests/minter_state/mod.rs new file mode 100644 index 0000000..d548fdf --- /dev/null +++ b/tests/minter_state/mod.rs @@ -0,0 +1 @@ +pub mod minter_state; From 0cb91d2eac9fe54b19a3e32b103aa627159fca8e Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:56:01 +0200 Subject: [PATCH 06/17] test: initialize contract feature tests Refs: #78 --- tests/endpoints/initialize_contract.rs | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/endpoints/initialize_contract.rs diff --git a/tests/endpoints/initialize_contract.rs b/tests/endpoints/initialize_contract.rs new file mode 100644 index 0000000..03f94c0 --- /dev/null +++ b/tests/endpoints/initialize_contract.rs @@ -0,0 +1,51 @@ +use multiversx_sc_scenario::scenario_model::TxExpect; + +use crate::minter_state::minter_state::{ + ContractsState, COLLECTION_NAME, DATA_NFT_IDENTIFIER_EXPR, ITHEUM_TOKEN_IDENTIFIER, + MINTER_OWNER_ADDRESS_EXPR, +}; + +#[test] +fn initialize_contract_test() { + let mut state = ContractsState::new(); + let treasury_address = state.treasury.clone(); + + state.deploy_minter(); + state.minter_initialize_contract( + MINTER_OWNER_ADDRESS_EXPR, + COLLECTION_NAME, + DATA_NFT_IDENTIFIER_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 25u64, + 10u64, + treasury_address.clone(), + Some(1u64), + Some(TxExpect::user_error("str:Issue cost is 0.05 eGLD")), + ); + + state.minter_initialize_contract( + MINTER_OWNER_ADDRESS_EXPR, + COLLECTION_NAME, + DATA_NFT_IDENTIFIER_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 25u64, + 10u64, + treasury_address.clone(), + None, + None, + ); + + state.mock_minter_initialized(ITHEUM_TOKEN_IDENTIFIER, 100u64, 10u64); + + state.minter_initialize_contract( + MINTER_OWNER_ADDRESS_EXPR, + COLLECTION_NAME, + DATA_NFT_IDENTIFIER_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 25u64, + 10u64, + treasury_address, + None, + Some(TxExpect::user_error("str:Contract was already initialized")), + ); +} From 11b81548998d64d28dca9b9a1dc4127bf5b1d25c Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:56:27 +0200 Subject: [PATCH 07/17] test: mint feature tests Refs: #78 --- tests/endpoints/mint.rs | 495 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 tests/endpoints/mint.rs diff --git a/tests/endpoints/mint.rs b/tests/endpoints/mint.rs new file mode 100644 index 0000000..5824ea4 --- /dev/null +++ b/tests/endpoints/mint.rs @@ -0,0 +1,495 @@ +use datanftmint::storage::DataNftAttributes; +use multiversx_sc_scenario::{ + api::SingleTxApi, + managed_address, managed_buffer, + scenario_model::{CheckAccount, CheckStateStep, SetStateStep, TxExpect}, +}; + +use crate::minter_state::minter_state::{ + ContractsState, BONDING_CONTRACT_ADDRESS_EXPR, BONDING_OWNER_ADDRESS_EXPR, + DATA_NFT_IDENTIFIER_EXPR, FIRST_USER_ADDRESS_EXPR, ITHEUM_TOKEN_IDENTIFIER, + ITHEUM_TOKEN_IDENTIFIER_EXPR, MINTER_CONTRACT_ADDRESS_EXPR, MINTER_OWNER_ADDRESS_EXPR, + TREAASURY_ADDRESS_EXPR, +}; + +#[test] +fn mint_test_without_anti_spam_tax_test() { + let mut state = ContractsState::new(); + + state.deploy_minter(); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-encoded-string", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Minting and burning not allowed")), + ); + + state + .mock_minter_initialized(ITHEUM_TOKEN_IDENTIFIER, 0u64, 10u64) + .unpause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Data Stream is empty")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "http://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL must start with https://")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL is empty")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL length is too small")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + &"https://".repeat(52), + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL length is too big")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "http://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL must start with https://")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "http://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:URL must start with https://")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "Test title", + "", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Field is empty")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + "", + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Field is empty")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(30), + "Test description", + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Too many characters")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(301), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Too many characters")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 10000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error( + "str:Royalties are bigger than max royalties", + )), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 21u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Max supply exceeded")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error( + "str:You need to wait more time before minting again", + )), + ); + + state + .world + .set_state_step(SetStateStep::new().block_timestamp(11u64)); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:You are not whitelisted")), + ); + + state.minter_disable_whitelist(MINTER_OWNER_ADDRESS_EXPR, None); + + state.deploy_bonding(); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10u64 + 100u64, + Some(TxExpect::user_error("str:Contract not ready")), + ); + + state.bond_contract_default_deploy_and_set(10u64, 100u64); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64, + None, + ); + + state.world.check_state_step( + CheckStateStep::new() + .put_account( + FIRST_USER_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "100"), // 200-100 = 100 + ) + .put_account( + MINTER_CONTRACT_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, ""), + ) + .put_account( + BONDING_CONTRACT_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "100"), // 100 for BOND + ), + ); +} + +#[test] +fn mint_with_anti_spam_tax_test_and_whitelist() { + let mut state = ContractsState::new(); + let first_user_address = state.first_user.clone(); + + state + .mock_minter_initialized(ITHEUM_TOKEN_IDENTIFIER, 100u64, 10u64) + .unpause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None) + .bond_contract_default_deploy_and_set(10u64, 100u64) + .bond_unpause_contract(BONDING_OWNER_ADDRESS_EXPR, None); + + state.minter_enable_whitelist(MINTER_OWNER_ADDRESS_EXPR, None); + + state + .world + .set_state_step(SetStateStep::new().block_timestamp(11u64)); + + state.minter_add_to_whitelist(MINTER_OWNER_ADDRESS_EXPR, first_user_address.clone(), None); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64, + Some(TxExpect::user_error("str:Not enough funds")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64 + 100u64, + None, + ); + + state.minter_remove_from_whitelist(MINTER_OWNER_ADDRESS_EXPR, first_user_address.clone(), None); + + let data_nft_attributes: DataNftAttributes = DataNftAttributes { + data_stream_url: managed_buffer!(b"random-url-encoded-here"), + data_preview_url: managed_buffer!(b"https://test.com/test"), + data_marshal_url: managed_buffer!(b"https://test.com/test"), + creator: managed_address!(&first_user_address), + creation_time: 11u64, + title: managed_buffer!(b"Test title"), + description: managed_buffer!(b"Test description"), + }; + + state.world.check_state_step( + CheckStateStep::new() + .put_account( + FIRST_USER_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "0"), // 200-100 (bond) - 100 (spam tax) = 0 + ) + .put_account( + MINTER_CONTRACT_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "0"), + ) + .put_account( + BONDING_CONTRACT_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "100"), // 100 for BOND + ) + .put_account( + TREAASURY_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "100"), + ) + .put_account( + FIRST_USER_ADDRESS_EXPR, + CheckAccount::new().esdt_nft_balance_and_attributes( + DATA_NFT_IDENTIFIER_EXPR, + 1u64, + "5", + Some(data_nft_attributes), + ), + ), + ); +} From f4e44bfa18bedd639a9c83e997847101e7191082 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:56:45 +0200 Subject: [PATCH 08/17] test: burn feature tests Refs: #78 --- tests/endpoints/burn.rs | 107 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 tests/endpoints/burn.rs diff --git a/tests/endpoints/burn.rs b/tests/endpoints/burn.rs new file mode 100644 index 0000000..61ca39b --- /dev/null +++ b/tests/endpoints/burn.rs @@ -0,0 +1,107 @@ +use datanftmint::storage::DataNftAttributes; +use multiversx_sc_scenario::{ + api::SingleTxApi, + managed_address, managed_buffer, + scenario_model::{CheckAccount, CheckStateStep, SetStateStep, TxExpect}, +}; + +use crate::minter_state::minter_state::{ + ContractsState, ANOTHER_TOKEN_IDENTIFIER, BONDING_OWNER_ADDRESS_EXPR, DATA_NFT_IDENTIFIER, + DATA_NFT_IDENTIFIER_EXPR, FIRST_USER_ADDRESS_EXPR, ITHEUM_TOKEN_IDENTIFIER, + MINTER_OWNER_ADDRESS_EXPR, +}; + +#[test] +fn burn_token_test() { + let mut state = ContractsState::new(); + let first_user_address = state.first_user.clone(); + + state + .mock_minter_initialized(ITHEUM_TOKEN_IDENTIFIER, 100u64, 10u64) + .unpause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None) + .bond_contract_default_deploy_and_set(10u64, 100u64) + .bond_unpause_contract(BONDING_OWNER_ADDRESS_EXPR, None); + + state.minter_disable_whitelist(MINTER_OWNER_ADDRESS_EXPR, None); + + state + .world + .set_state_step(SetStateStep::new().block_timestamp(11u64)); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64 + 100u64, + None, + ); + + state.pause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None); + + state.minter_burn( + FIRST_USER_ADDRESS_EXPR, + DATA_NFT_IDENTIFIER, + 1u64, + 2u64, + Some(TxExpect::user_error("str:Minting and burning not allowed")), + ); + + state.unpause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None); + + state.minter_burn( + FIRST_USER_ADDRESS_EXPR, + ANOTHER_TOKEN_IDENTIFIER, + 0, + 2u64, + Some(TxExpect::user_error("str:Invalid payment token")), + ); + + state.minter_burn( + FIRST_USER_ADDRESS_EXPR, + DATA_NFT_IDENTIFIER, + 1u64, + 0u64, + Some(TxExpect::user_error("str:Value must be higher than zero")), + ); + + state.minter_burn( + FIRST_USER_ADDRESS_EXPR, + DATA_NFT_IDENTIFIER, + 1u64, + 3u64, + None, + ); + + let data_nft_attributes: DataNftAttributes = DataNftAttributes { + data_stream_url: managed_buffer!(b"random-url-encoded-here"), + data_preview_url: managed_buffer!(b"https://test.com/test"), + data_marshal_url: managed_buffer!(b"https://test.com/test"), + creator: managed_address!(&first_user_address), + creation_time: 11u64, + title: managed_buffer!(b"Test title"), + description: managed_buffer!(b"Test description"), + }; + + state + .world + .check_state_step(CheckStateStep::new().put_account( + FIRST_USER_ADDRESS_EXPR, + CheckAccount::new().esdt_nft_balance_and_attributes( + DATA_NFT_IDENTIFIER_EXPR, + 1u64, + "2", + Some(data_nft_attributes), + ), + )); +} From f42869f709a7e9006222d2cd9d80801e3eb30e78 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:57:04 +0200 Subject: [PATCH 09/17] test: deploy and upgrade feature tests Refs: #78 --- tests/endpoints/deploy_ungrade.rs | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/endpoints/deploy_ungrade.rs diff --git a/tests/endpoints/deploy_ungrade.rs b/tests/endpoints/deploy_ungrade.rs new file mode 100644 index 0000000..61ff467 --- /dev/null +++ b/tests/endpoints/deploy_ungrade.rs @@ -0,0 +1,39 @@ +use datanftmint::storage::ProxyTrait as _; +use multiversx_sc::storage::mappers::SingleValue; +use multiversx_sc_scenario::scenario_model::ScQueryStep; + +use crate::minter_state::minter_state::{ + ContractsState, MINTER_ADMIN_ADDRESS_EXPR, MINTER_OWNER_ADDRESS_EXPR, +}; + +#[test] +fn deploy_and_upgrade_minter_test() { + let mut state = ContractsState::new(); + let admin = state.admin.clone(); + + state + .deploy_minter() + .minter_set_administarator(MINTER_OWNER_ADDRESS_EXPR, admin, None); + + state.world.sc_query( + ScQueryStep::new() + .call(state.minter_contract.is_paused()) + .expect_value(SingleValue::from(true)), + ); + + state.unpause_minter_contract(MINTER_ADMIN_ADDRESS_EXPR, None); + + state.world.sc_query( + ScQueryStep::new() + .call(state.minter_contract.is_paused()) + .expect_value(SingleValue::from(false)), + ); + + state.minter_upgrade(); + + state.world.sc_query( + ScQueryStep::new() + .call(state.minter_contract.is_paused()) + .expect_value(SingleValue::from(true)), + ); +} From 3570573127ab0397b91050d5a3b02ab1e9fc345d Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:57:27 +0200 Subject: [PATCH 10/17] test: withdraw feature tests Refs: #78 --- tests/endpoints/withdraw.rs | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 tests/endpoints/withdraw.rs diff --git a/tests/endpoints/withdraw.rs b/tests/endpoints/withdraw.rs new file mode 100644 index 0000000..a30d479 --- /dev/null +++ b/tests/endpoints/withdraw.rs @@ -0,0 +1,66 @@ +use multiversx_sc_scenario::scenario_model::{ + AddressValue, CheckAccount, CheckStateStep, TransferStep, TxExpect, +}; + +use crate::minter_state::minter_state::{ + ContractsState, BONDING_OWNER_ADDRESS_EXPR, ITHEUM_TOKEN_IDENTIFIER, + ITHEUM_TOKEN_IDENTIFIER_EXPR, MINTER_CONTRACT_ADDRESS_EXPR, MINTER_OWNER_ADDRESS_EXPR, + THIRD_USER_ADDRESS_EXPR, WITHDRAWAL_ADDRESS_EXPR, +}; + +#[test] +fn withdraw_test() { + let mut state = ContractsState::new(); + + state + .mock_minter_initialized(ITHEUM_TOKEN_IDENTIFIER, 100u64, 10u64) + .unpause_minter_contract(MINTER_OWNER_ADDRESS_EXPR, None) + .bond_contract_default_deploy_and_set(10u64, 100u64) + .bond_unpause_contract(BONDING_OWNER_ADDRESS_EXPR, None); + + state.world.transfer_step( + TransferStep::new() + .from(THIRD_USER_ADDRESS_EXPR) + .to(MINTER_CONTRACT_ADDRESS_EXPR) + .esdt_transfer(ITHEUM_TOKEN_IDENTIFIER, 0u64, 100u64), + ); + + state.minter_withdraw( + MINTER_OWNER_ADDRESS_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64, + Some(TxExpect::user_error("str:Withdrawal address not set")), + ); + + state.set_withdrawal_address( + MINTER_OWNER_ADDRESS_EXPR, + AddressValue::from(WITHDRAWAL_ADDRESS_EXPR).to_address(), + None, + ); + + state.minter_withdraw( + MINTER_OWNER_ADDRESS_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64, + Some(TxExpect::user_error( + "str:Only withdrawal address can withdraw tokens", + )), + ); + + state.minter_withdraw( + WITHDRAWAL_ADDRESS_EXPR, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 100u64, + None, + ); + + state + .world + .check_state_step(CheckStateStep::new().put_account( + WITHDRAWAL_ADDRESS_EXPR, + CheckAccount::new().esdt_balance(ITHEUM_TOKEN_IDENTIFIER_EXPR, "100"), + )); +} From 3416e658676e365e61067888e002849f4a72fa89 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:58:04 +0200 Subject: [PATCH 11/17] test: export tests Refs: #78 --- tests/endpoints/collection_management.rs | 4 ++++ tests/endpoints/mod.rs | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/endpoints/collection_management.rs create mode 100644 tests/endpoints/mod.rs diff --git a/tests/endpoints/collection_management.rs b/tests/endpoints/collection_management.rs new file mode 100644 index 0000000..221dad9 --- /dev/null +++ b/tests/endpoints/collection_management.rs @@ -0,0 +1,4 @@ +#[test] +fn collection_management_test() { + //NOT IMPLEMENTED +} diff --git a/tests/endpoints/mod.rs b/tests/endpoints/mod.rs new file mode 100644 index 0000000..4d9dc4a --- /dev/null +++ b/tests/endpoints/mod.rs @@ -0,0 +1,7 @@ +mod burn; +mod deploy_ungrade; +mod initialize_contract; +mod mint; +mod withdraw; + +mod collection_management; From c21ffe4bef872e58bf8779bcabaf431e0d4d7616 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 16:58:52 +0200 Subject: [PATCH 12/17] chore: update coverage workflow Refs: #78 --- .github/workflows/coverage.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7c0d07c..a3d64dd 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - main + - develop jobs: coverage: runs-on: ubuntu-latest @@ -12,7 +13,7 @@ jobs: - name: Install latest nightly uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: nightly-2024-02-27 override: true components: rustfmt, clippy - name: Install cargo-llvm-cov @@ -20,7 +21,7 @@ jobs: - name: Making coverage dir run: mkdir coverage - name: Generate code coverage - run: cargo llvm-cov --lcov --output-path coverage/lcov.info --ignore-filename-regex '(callbacks.rs|views.rs|events.rs|storage.rs)' + run: cargo llvm-cov --lcov --output-path coverage/lcov.info --ignore-filename-regex '(storage.rs|events.rs)' - name: Generating report uses: vebr/jest-lcov-reporter@v0.2.0 with: From 349ebdad37b13477b0d7c586e4c975ec395e0461 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Thu, 7 Mar 2024 17:04:36 +0200 Subject: [PATCH 13/17] chore: ignore files Refs: #78 --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a3d64dd..4f33a2b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -21,7 +21,7 @@ jobs: - name: Making coverage dir run: mkdir coverage - name: Generate code coverage - run: cargo llvm-cov --lcov --output-path coverage/lcov.info --ignore-filename-regex '(storage.rs|events.rs)' + run: cargo llvm-cov --lcov --output-path coverage/lcov.info --ignore-filename-regex '(callbacks.rs|views.rs|events.rs|storage.rs)' - name: Generating report uses: vebr/jest-lcov-reporter@v0.2.0 with: From a91703aa678c5a5891c7769a503bf8c9d28f6c8f Mon Sep 17 00:00:00 2001 From: Bucur David Date: Fri, 8 Mar 2024 08:06:20 +0200 Subject: [PATCH 14/17] fix: improve logic Refs: #78 --- src/errors.rs | 2 +- src/lib.rs | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index e7631da..2404182 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -36,4 +36,4 @@ pub const ERR_TOO_MANY_CHARS: &str = "Too many characters"; pub const ERR_ONLY_WITHDRAWAL_ADDRESS_CAN_WITHDRAW: &str = "Only withdrawal address can withdraw tokens"; pub const ERR_WITHDRAWAL_ADDRESS_NOT_SET: &str = "Withdrawal address not set"; -pub const ERR_NOT_ENOUGH_FUNDS: &str = "Not enough funds"; +pub const ERR_WRONG_AMOUNT_OF_FUNDS: &str = "Wrong amount of funds"; diff --git a/src/lib.rs b/src/lib.rs index 9b35066..4ca59f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ use crate::{ callbacks::CallbackProxy, errors::{ ERR_ALREADY_IN_WHITELIST, ERR_CONTRACT_ALREADY_INITIALIZED, ERR_DATA_STREAM_IS_EMPTY, - ERR_ISSUE_COST, ERR_NOT_ENOUGH_FUNDS, ERR_NOT_IN_WHITELIST, ERR_WHITELIST_IS_EMPTY, + ERR_ISSUE_COST, ERR_NOT_IN_WHITELIST, ERR_WHITELIST_IS_EMPTY, ERR_WRONG_AMOUNT_OF_FUNDS, }, storage::DataNftAttributes, }; @@ -171,23 +171,19 @@ pub trait DataNftMint: let bond_amount = self.get_bond_amount_for_lock_period(lock_period_sec); - if price >= BigUint::zero() { - require!( - payment.amount >= &price + &bond_amount, - ERR_NOT_ENOUGH_FUNDS - ); + require!( + payment.amount == &price + &bond_amount, + ERR_WRONG_AMOUNT_OF_FUNDS + ); - self.send().direct( - &treasury_address, - &payment.token_identifier, - payment.token_nonce, - &price, - ); + payment.amount -= &price; - payment.amount -= &price; - } else { - require!(payment.amount == bond_amount, ERR_NOT_ENOUGH_FUNDS); - } + self.send().direct_non_zero( + &treasury_address, + &payment.token_identifier, + payment.token_nonce, + &price, + ); let one_token = BigUint::from(1u64); self.minted_per_address(&caller) @@ -394,7 +390,7 @@ pub trait DataNftMint: self.withdraw_tokens_event(&caller, &token_identifier, &amount); } else { - sc_panic!(ERR_NOT_ENOUGH_FUNDS); + sc_panic!(ERR_WRONG_AMOUNT_OF_FUNDS); } } } From aef5a8b126229cb5c7ccaed783a0ef31de923987 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Fri, 8 Mar 2024 08:06:54 +0200 Subject: [PATCH 15/17] test: mint feature tests update Refs: #78 --- tests/endpoints/mint.rs | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/tests/endpoints/mint.rs b/tests/endpoints/mint.rs index 5824ea4..0ed6060 100644 --- a/tests/endpoints/mint.rs +++ b/tests/endpoints/mint.rs @@ -353,12 +353,31 @@ fn mint_test_without_anti_spam_tax_test() { 10u64, ITHEUM_TOKEN_IDENTIFIER, 0u64, - 10u64 + 100u64, + 0u64, // testing that bonding is not ready Some(TxExpect::user_error("str:Contract not ready")), ); state.bond_contract_default_deploy_and_set(10u64, 100u64); + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 10 + 100u64, + Some(TxExpect::user_error("str:Wrong amount of funds")), + ); + state.minter_mint( FIRST_USER_ADDRESS_EXPR, "Test", @@ -430,7 +449,26 @@ fn mint_with_anti_spam_tax_test_and_whitelist() { ITHEUM_TOKEN_IDENTIFIER, 0u64, 100u64, - Some(TxExpect::user_error("str:Not enough funds")), + Some(TxExpect::user_error("str:Wrong amount of funds")), + ); + + state.minter_mint( + FIRST_USER_ADDRESS_EXPR, + "Test", + "https://test.com/test", + "https://test.com/test", + "https://test.com/test", + "random-url-encoded-here", + "https://test.com/test", + 1000u64, + 5u64, + &"Test title".repeat(1), + &"Test description".repeat(1), + 10u64, + ITHEUM_TOKEN_IDENTIFIER, + 0u64, + 99u64 + 100u64, + Some(TxExpect::user_error("str:Wrong amount of funds")), ); state.minter_mint( From 4808d1ab2f7750dd1203ab68c860d52845448f81 Mon Sep 17 00:00:00 2001 From: Bucur David Date: Mon, 11 Mar 2024 10:31:38 +0200 Subject: [PATCH 16/17] fix: require bond amount greater than zero Refs: # 77 --- src/errors.rs | 1 + src/lib.rs | 3 +++ tests/endpoints/mint.rs | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 2404182..53a6896 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -37,3 +37,4 @@ pub const ERR_ONLY_WITHDRAWAL_ADDRESS_CAN_WITHDRAW: &str = "Only withdrawal address can withdraw tokens"; pub const ERR_WITHDRAWAL_ADDRESS_NOT_SET: &str = "Withdrawal address not set"; pub const ERR_WRONG_AMOUNT_OF_FUNDS: &str = "Wrong amount of funds"; +pub const ERR_WRONG_BOND_PERIOD: &str = "Wrong bond period"; diff --git a/src/lib.rs b/src/lib.rs index 4ca59f3..2be9e56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ use crate::{ errors::{ ERR_ALREADY_IN_WHITELIST, ERR_CONTRACT_ALREADY_INITIALIZED, ERR_DATA_STREAM_IS_EMPTY, ERR_ISSUE_COST, ERR_NOT_IN_WHITELIST, ERR_WHITELIST_IS_EMPTY, ERR_WRONG_AMOUNT_OF_FUNDS, + ERR_WRONG_BOND_PERIOD, }, storage::DataNftAttributes, }; @@ -171,6 +172,8 @@ pub trait DataNftMint: let bond_amount = self.get_bond_amount_for_lock_period(lock_period_sec); + require!(bond_amount > BigUint::zero(), ERR_WRONG_BOND_PERIOD); + require!( payment.amount == &price + &bond_amount, ERR_WRONG_AMOUNT_OF_FUNDS diff --git a/tests/endpoints/mint.rs b/tests/endpoints/mint.rs index 0ed6060..c7887e5 100644 --- a/tests/endpoints/mint.rs +++ b/tests/endpoints/mint.rs @@ -353,8 +353,8 @@ fn mint_test_without_anti_spam_tax_test() { 10u64, ITHEUM_TOKEN_IDENTIFIER, 0u64, - 0u64, // testing that bonding is not ready - Some(TxExpect::user_error("str:Contract not ready")), + 0u64, + Some(TxExpect::user_error("str:Wrong bond period")), ); state.bond_contract_default_deploy_and_set(10u64, 100u64); From a6f51be7b52437ba96505d09a2f07592b6ef9c8e Mon Sep 17 00:00:00 2001 From: Damian Date: Mon, 11 Mar 2024 12:43:55 +0200 Subject: [PATCH 17/17] chore: upgrade mx-sdk-rs to 0.47.5 --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 5 +++-- meta/Cargo.lock | 12 ++++++------ meta/Cargo.toml | 4 ++-- wasm/Cargo.lock | 12 ++++++------ wasm/Cargo.toml | 2 +- wasm/src/lib.rs | 6 ------ 7 files changed, 26 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69db98f..2806029 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -936,9 +936,9 @@ checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" [[package]] name = "multiversx-sc" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b69a83a9423be4b543edee969205aa43ef4397c48b965a65bad857e022db5c" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ "bitflags 2.4.2", "hex-literal", @@ -972,9 +972,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6400e2f4e57f7c9c00ad76108794aa962657cf62b4d4f49b99f02d9a6ba5" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", @@ -985,9 +985,9 @@ dependencies = [ [[package]] name = "multiversx-sc-meta" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dec6cc0735acb48fce290b367c9d22684103055f00a7dec057840fc134973d" +checksum = "3522f14ef47b1516a6635e86e0c19acffd8d328eb194a90c29b05d09a22c5296" dependencies = [ "clap", "colored", @@ -1012,9 +1012,9 @@ dependencies = [ [[package]] name = "multiversx-sc-scenario" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71bc382a5ba02deb9452ec29453806c176200ee5d0e5c7c948f52dc84181382" +checksum = "dd121a50905b4da3f85750ab3c4f283738245ad22e619b50da2588d1528e4240" dependencies = [ "base64", "bech32", diff --git a/Cargo.toml b/Cargo.toml index 2fad88d..71878ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,11 @@ authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum" [lib] path = "src/lib.rs" + [dependencies.multiversx-sc] -version = "0.47.4" +version = "0.47.5" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.4" +version = "0.47.5" [dev-dependencies] diff --git a/meta/Cargo.lock b/meta/Cargo.lock index 7b7b326..29d6b18 100644 --- a/meta/Cargo.lock +++ b/meta/Cargo.lock @@ -709,9 +709,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b69a83a9423be4b543edee969205aa43ef4397c48b965a65bad857e022db5c" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ "bitflags 2.4.2", "hex-literal", @@ -745,9 +745,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6400e2f4e57f7c9c00ad76108794aa962657cf62b4d4f49b99f02d9a6ba5" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", @@ -758,9 +758,9 @@ dependencies = [ [[package]] name = "multiversx-sc-meta" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dec6cc0735acb48fce290b367c9d22684103055f00a7dec057840fc134973d" +checksum = "3522f14ef47b1516a6635e86e0c19acffd8d328eb194a90c29b05d09a22c5296" dependencies = [ "clap", "colored", diff --git a/meta/Cargo.toml b/meta/Cargo.toml index 7a9ccd1..21ab852 100644 --- a/meta/Cargo.toml +++ b/meta/Cargo.toml @@ -10,7 +10,7 @@ authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum" path = ".." [dependencies.multiversx-sc] -version = "0.47.4" +version = "0.47.5" [dependencies.multiversx-sc-meta] -version = "0.47.4" +version = "0.47.5" diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 3752266..3288287 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -55,9 +55,9 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b69a83a9423be4b543edee969205aa43ef4397c48b965a65bad857e022db5c" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ "bitflags", "hex-literal", @@ -90,9 +90,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6400e2f4e57f7c9c00ad76108794aa962657cf62b4d4f49b99f02d9a6ba5" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.4" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304900b34dfae6fd5baddd4c98345f1b7fa7e839257dac961023733be40dd81e" +checksum = "e7e6e0330769b8b46966c5fc59fd13bd95a0d5b330cf0aa55c0403dbb911fa71" dependencies = [ "multiversx-sc", ] diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index f073c2e..69e3da5 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -25,7 +25,7 @@ overflow-checks = false path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.4" +version = "0.47.5" [workspace] members = ["."] diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index a2e7a71..0fc1b9a 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -5,15 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -<<<<<<< HEAD // Endpoints: 48 // Async Callback: 1 // Total number of exported functions: 50 -======= -// Endpoints: 46 -// Async Callback: 1 -// Total number of exported functions: 48 ->>>>>>> develop #![no_std] #![allow(internal_features)]