diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7c0d07c..4f33a2b 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 diff --git a/Cargo.lock b/Cargo.lock index a0632a9..2806029 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,38 +27,20 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[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 = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[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", @@ -70,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" @@ -85,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", ] @@ -104,26 +86,15 @@ 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" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "atty" -version = "0.2.14" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" @@ -148,21 +119,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bech32" @@ -177,8 +136,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand", - "rand_core", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -197,9 +156,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block-buffer" @@ -207,30 +166,23 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] [[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 = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[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", @@ -238,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" @@ -256,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" @@ -268,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", @@ -278,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", @@ -290,21 +242,21 @@ 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", "quote", - "syn 2.0.39", + "syn", ] [[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" @@ -314,13 +266,12 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "atty", "lazy_static", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -329,12 +280,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" -[[package]] -name = "const-oid" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" - [[package]] name = "convert_case" version = "0.6.0" @@ -369,99 +314,89 @@ 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 = "crypto-common" -version = "0.1.6" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "generic-array", - "typenum", + "crossbeam-utils", ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "crossbeam-utils" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "subtle", + "typenum", ] [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.6", - "fiat-crypto", - "platforms", - "rustc_version", + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", "subtle", "zeroize", ] -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "datanftmint" -version = "2.0.0" +version = "3.0.0" dependencies = [ + "core-mx-life-bonding-sc", "multiversx-sc", "multiversx-sc-scenario", ] -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "digest" version = "0.9.0" @@ -473,52 +408,43 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] name = "ed25519" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" -dependencies = [ - "signature 1.6.0", -] - -[[package]] -name = "ed25519" -version = "2.2.3" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "pkcs8", - "signature 2.1.0", + "signature", ] [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", - "ed25519 2.2.3", + "ed25519", + "rand 0.7.3", "serde", - "sha2 0.10.6", - "subtle", + "sha2 0.9.9", "zeroize", ] [[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" @@ -557,12 +483,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" -[[package]] -name = "fiat-crypto" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" - [[package]] name = "flate2" version = "1.0.28" @@ -605,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", @@ -653,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", @@ -663,13 +583,24 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -680,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", @@ -703,28 +634,18 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "heck" @@ -734,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" @@ -761,19 +673,18 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac", - "digest 0.9.0", + "digest 0.10.7", ] [[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", @@ -782,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", @@ -805,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", @@ -820,7 +731,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -852,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]] @@ -895,33 +795,36 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[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", ] [[package]] name = "keccak" -version = "0.1.0" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] [[package]] name = "lazy_static" @@ -931,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" @@ -953,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" @@ -974,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", @@ -994,9 +894,9 @@ dependencies = [ [[package]] name = "multiversx-chain-scenario-format" -version = "0.21.0" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c57b56954b133e76bfe77e1f20a903983f25fd24d53b28fe9cc9c9e54f374d2f" +checksum = "7a9190bdd56300e801e7793fc4ee7dc0c76c1149aac019da8c71cc58254966fe" dependencies = [ "bech32", "hex", @@ -1004,16 +904,17 @@ dependencies = [ "num-traits", "serde", "serde_json", - "sha3 0.9.1", + "sha3", ] [[package]] name = "multiversx-chain-vm" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3c6d36157be3a413daef246de14c8c9465bea53b985941593aa741423722ce" +checksum = "a363734a77774f4095fad6f49c6772b82edd833ed47a7c1ca87db18f68ccfffd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", + "colored", "ed25519-dalek", "hex", "hex-literal", @@ -1021,10 +922,10 @@ dependencies = [ "multiversx-chain-vm-executor", "num-bigint", "num-traits", - "rand", + "rand 0.8.5", "rand_seeder", - "sha2 0.10.6", - "sha3 0.10.6", + "sha2 0.10.8", + "sha3", ] [[package]] @@ -1035,12 +936,11 @@ checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" [[package]] name = "multiversx-sc" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11b51d6a2ab0218585ed58e100c5ac2218de09490fbfc4243b5ecd0ca7f5cbc" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ - "bitflags 1.3.2", - "hashbrown 0.14.3", + "bitflags 2.4.2", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -1049,9 +949,9 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327b0ad1c3477cab0d7c84391439ba302238f738ef3c6e1fcd18e247fba84875" +checksum = "1da6db65170105c9495848c5e4ba388abb1f9201ff2ca362056c9328f36b7760" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", @@ -1060,34 +960,34 @@ dependencies = [ [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f444038e0043b8eda816b26952479c2aca3c4a643580f4337f71fb362a586db5" +checksum = "631c4d4b37fc94659c8d6cf559c21b68c68899095201de2e1b779fccad7b0b03" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.91", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784f0fc505806102fe6f808b368e12fcb13096dd73c5678f09c5663230724d6f" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.91", + "syn", ] [[package]] name = "multiversx-sc-meta" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3fad2491d11c6edf3fe131696be31743dc568457c013b2c256e56376da294b" +checksum = "3522f14ef47b1516a6635e86e0c19acffd8d328eb194a90c29b05d09a22c5296" dependencies = [ "clap", "colored", @@ -1101,21 +1001,22 @@ dependencies = [ "reqwest", "ruplacer", "rustc_version", + "semver", "serde", "serde_json", "toml", - "wasmparser 0.116.1", + "wasmparser", "wasmprinter", "zip", ] [[package]] name = "multiversx-sc-scenario" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285a6021a379c069cce06f5b6ba6b562ea63fb1c1fd252b031993e5f32e9e440" +checksum = "dd121a50905b4da3f85750ab3c4f283738245ad22e619b50da2588d1528e4240" dependencies = [ - "base64 0.13.1", + "base64", "bech32", "clap", "colored", @@ -1133,33 +1034,32 @@ dependencies = [ "pathdiff", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "tokio", ] [[package]] name = "multiversx-sdk" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baedd8e9f73ddee5a21964cde188397363c50bd43f1c12ee3dde20d15307cff" +checksum = "46d709ddf46c50a407ce4b90ff487e854926d47f80de6abfe4a4adca3eaa7964" dependencies = [ "anyhow", - "base64 0.13.1", + "base64", "bech32", "bip39", - "ed25519 1.5.2", "hex", "hmac", "itertools", "pbkdf2", "pem", - "rand", + "rand 0.8.5", "reqwest", "serde", "serde_json", "serde_repr", - "sha2 0.9.9", - "sha3 0.9.1", + "sha2 0.10.8", + "sha3", "tokio", "zeroize", ] @@ -1193,9 +1093,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1204,19 +1104,18 @@ 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", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -1227,38 +1126,38 @@ 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.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -1275,7 +1174,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -1286,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", @@ -1327,20 +1226,21 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "crypto-mac", + "digest 0.10.7", ] [[package]] name = "pem" -version = "1.1.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ - "base64 0.13.1", + "base64", + "serde", ] [[package]] @@ -1361,48 +1261,32 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - [[package]] name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.2.0" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +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" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1417,6 +1301,19 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -1424,8 +1321,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -1435,16 +1342,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] name = "rand_core" -version = "0.6.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -1453,7 +1378,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1467,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", @@ -1478,17 +1415,17 @@ 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 0.21.5", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1506,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", @@ -1522,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", @@ -1552,22 +1490,31 @@ 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.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", "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" @@ -1580,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]] @@ -1618,37 +1565,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.7" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" +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", - "syn 2.0.39", + "syn", ] [[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", @@ -1656,20 +1603,20 @@ 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", - "syn 2.0.39", + "syn", ] [[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", ] @@ -1701,34 +1648,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", + "digest 0.10.7", ] [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] @@ -1743,15 +1678,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ea32af43239f0d353a7dd75a22d94c329c8cdaafdcb4c1c1335aa10c298a4a" - -[[package]] -name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "slab" @@ -1764,73 +1693,48 @@ 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", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", + "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" -version = "1.0.91" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "syn" -version = "2.0.39" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" @@ -1855,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]] @@ -1892,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", @@ -1904,7 +1798,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -1917,7 +1811,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -1946,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", @@ -1968,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", @@ -2006,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" @@ -2039,15 +1933,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode-xid" -version = "0.2.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "url" @@ -2080,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", ] @@ -2100,9 +1987,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" @@ -2112,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", @@ -2122,24 +2009,24 @@ 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", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn", "wasm-bindgen-shared", ] [[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", @@ -2149,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", @@ -2159,58 +2046,49 @@ 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", - "syn 2.0.39", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" - -[[package]] -name = "wasmparser" -version = "0.116.1" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" -dependencies = [ - "indexmap 2.1.0", - "semver", -] +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasmparser" -version = "0.118.1" +version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ - "indexmap 2.1.0", + "bitflags 2.4.2", + "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", @@ -2234,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", ] @@ -2262,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]] @@ -2282,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]] @@ -2303,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" @@ -2315,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" @@ -2327,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" @@ -2339,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" @@ -2351,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" @@ -2363,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" @@ -2375,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", ] @@ -2399,31 +2277,25 @@ dependencies = [ ] [[package]] -name = "zerocopy" -version = "0.7.28" +name = "zeroize" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ - "zerocopy-derive", + "zeroize_derive", ] [[package]] -name = "zerocopy-derive" -version = "0.7.28" +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" - [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index 43fa087..71878ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,18 @@ [package] name = "datanftmint" -version = "2.0.0" +version = "3.0.0" edition = "2021" publish = false authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum"] [lib] path = "src/lib.rs" + [dependencies.multiversx-sc] -version = "0.45.1" +version = "0.47.5" [dev-dependencies.multiversx-sc-scenario] -version = "0.45.1" +version = "0.47.5" + + +[dev-dependencies] +core-mx-life-bonding-sc = {git = "https://github.com/Itheum/core-mx-life-bonding-sc"} diff --git a/README.md b/README.md index 69009a5..b5a588d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Itheum Core Elrond - NFT-FT Minter Smart Contract +# Itheum Core MultiversX - NFT-FT Minter Smart Contract ## Abstract @@ -6,453 +6,33 @@ The Data NFT Minting contract is a tool that can be used in order to tokenize an ## Introduction -This contract allows the owner of it to create an SFT collection towards which anyone can contribute by creating Data NFTs. The creators can even choose their own royalties or supply. +This contract allows the owner of it to create a SFT collection towards which anyone can contribute by creating Data NFTs. The creators can even choose their own royalties or supply. ## Prerequisites -This documentation assumes the user has previous programming experience. Moreover, the user should have a basic understanding of the Elrond blockchain. If you are new to the blockchain, please refer to the [Elrond documentation](https://docs.elrond.com/). In order to develop Elrond smart contract related solutions, one needs to have installed [mxpy](https://docs.multiversx.com/sdk-and-tools/sdk-py/installing-mxpy). +This documentation assumes the user has previous programming experience. Moreover, the user should have a basic understanding of the MultiversX blockchain. If you are new to the blockchain, please refer to the [MultiversX documentation](https://docs.multiversx.com/). In order to develop MultiversX smart contract related solutions, one needs to have installed [mxpy](https://docs.multiversx.com/sdk-and-tools/sdk-py/installing-mxpy). -Understanding this document is also easier if one knows how [ESDT token transactions](https://docs.elrond.com/developers/esdt-tokens/#transfers-to-a-smart-contract) are structured on the Elrond blockchain and how [NFT tokens](https://docs.elrond.com/tokens/nft-tokens/) work on the Elrond Blockchain. +Understanding this document is also easier if one knows how [ESDT token transactions](https://docs.multiversx.com/developers/esdt-tokens/#transfers-to-a-smart-contract) are structured on the MultiversX blockchain and how [NFT tokens](https://docs.multiversx.com/tokens/nft-tokens/) work on the MultiversX Blockchain. -## Itheum deployed SFT mint & sale contract addresses +## Itheum deployed contract addresses -| Devnet | Mainnet | -| ---------------- | ---------------- | -| Not deployed yet | Not deployed yet | +| Devnet | Mainnet | +| -------------------------------------------------------------- | ------------------------------------------------------------------ | +| erd1qqqqqqqqqqqqqpgq7thwlde9hvc5ty7lx2j3l9tvy3wgkwu7fsxsvz9rat | erd1qqqqqqqqqqqqqpgqmuzgkurn657afd3r2aldqy2snsknwvrhc77q3lj8l6 yet | ## Endpoints -### Setup endpoints - -The setup workflow for the smart contract is as follows: - -- The SC deployment -- Setting up the collection -- Setting up the parameters used in creating Data NFT-FT - -#### init - -```rust - #[init] - fn init(&self); -``` - -The init function is called when deploying or upgrading the smart contract. It receives no arguments and does the following: pauses the contract, enable whitelist and sets the default values for minimum royalties, maximum royalties and maximum supply. - -### Only owner endpoints - -#### initializeContract - -```rust -#[payable("EGLD")] - #[endpoint(initializeContract)] - fn initialize_contract( - &self, - collection_name: ManagedBuffer, - token_ticker: ManagedBuffer, - token_identifier: &EgldOrEsdtTokenIdentifier, - anti_spam_tax: BigUint, - mint_time_limit: u64, - treasury_address: ManagedAddress - ); -``` - -Endpoint that initializes all the data needed for the smart contract to issue the token. The anti spam tax and mint time limit variables are used for regulating the minting of Data NFT-FTs. It can only be used once and it can only be called by the owner of the smart contract. In order for the call to work, the caller must also send 0.05 eGLD when calling the endpoint. This is to cover the cost of creating the Data NFT-FT collection. - -Call structure: "initializeContract" + "@" + collection_name hex encoded + "@" + token_ticker hex encoded + "@" + token_identifier hex encoded + "@" + anti_spam_tax + "@" + mint_time_limit hex encoded + "@" + treasury_address hex encoded. - -Example: "initializeContract@436f6c6c656374696f6e4e616d65@4e46544654@2049544845554d2d613631333137@015af1d78b58c40000@0384@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### setTreasuryAddress - -```rust - fn set_treasury_address(&self, - address: ManagedAddress - ); -``` - -Endpoint that sets the treasury address. The treasury address is the address that will receive the anti spam tax when minting a Data NFT-FT. - -Call structure: "setTreasuryAddress" + "@" + address hex encoded. - -Example: "setTreasuryAddress@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### pause - -```rust - #[endpoint(pause)] - fn pause_collection(&self); -``` - -Endpoint that pauses the entire collection. No transactions, minting, burning can be made on the collection while it is paused. - -Call structure: "pause" - -Example: "pause" - -#### unpause - -```rust - #[endpoint(unpause)] - fn unpause_collection(&self); -``` - -Endpoint that unpauses the entire collection. Normal transactions, minting, burning can be made on the collection while it is unpaused. - -Call structure: "unpause" - -Example: "unpause" - -#### freeze - -```rust - #[endpoint(freeze)] - fn freeze_collection_for_address( - &self, - address: &ManagedAddress - ); -``` - -Endpoint that freezes the entire collection for a specific address. It will utilize the token issued previously and owned by the smart contract. The freezed address will not be able to interact with the collection. - -Call structure: "freeze" + "@" + address hex encoded. - -Example: "freeze@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### unfreeze - -```rust - #[endpoint(unfreeze)] - fn unfreeze_collection_for_address( - &self, - address: &ManagedAddress - ); -``` - -Endpoint that unfreezes the entire collection for a specific address. It will utilize the token issued previously and owned by the smart contract. The unfreezed address will be able to interact with the collection. - -Call structure: "unfreeze" + "@" + address hex encoded. - -Example: "unfreeze@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### setMintTimeLimit - -```rust - #[endpoint(setMintTimeLimit)] - fn set_mint_time_limit( - &self, - mint_time_limit: u64 - ); -``` - -Endpoint that sets a time limit for the mint. An address can mint only once in the time limit. - -Call structure: "setMintTimeLimit" +"@" + mint_time_limit hex encoded. - -Example: "setMintTimeLimit@0384" - -#### setAdministrator - -```rust - #[endpoint(setAdministrator)] - fn set_administrator( - &self, - administrator: ManagedAddress - ); -``` - -Endpoint that sets the administrator of the contract. The administrator has some privileges that will be presented in the [Owner and administrator endpoints](#owner-and-administrator-endpoints) section. - -Call structure: "setAdministrator" + "@" + administrator hex encoded. - -Example: "setAdministrator@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### setWithdrawalAddress - -```rust - #[endpoint(setWithdrawalAddress)] - fn set_withdrawal_address( - &self, - withdrawal_address: ManagedAddress - ); -``` - -Endpoint that sets the withdrawal address. The withdrawal address is the address that will receive the funds from the smart contract. - -Call structure: "setWithdrawalAddress" + "@" + withdrawal_address hex encoded. - -Example: "setWithdrawalAddress@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -### Owner and administrator endpoints - -#### freezeSingleNFT - -```rust - #[endpoint(freezeSingleNFT)] - fn freeze_single_token_for_address( - &self, - nonce: u64, - address: &ManagedAddress - ); -``` - -Endpoint that freezes specific data NFT-FT for a specific address. It will utilize the token issued previously and owned by the smart contract and the nonce of the data NFT-FT. The freezed address will not be able to interact with the specifc data NFT-FT. - -Call structure: "freezeSingleNFT" + "@" + nonce hex encoded + "@" + address hex encoded. - -Example: "freezeSingleNFT@05@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### unFreezeSingleNFT - -```rust - #[endpoint(unFreezeSingleNFT)] - fn unfreeze_single_token_for_address( - &self, - nonce: u64, - address: &ManagedAddress - ); -``` - -Endpoint that unfreezes specific data NFT-FT for a specific address. It will utilize the token issued previously and owned by the smart contract and the nonce of the data NFT-FT. The unfreezed address will be able to interact with the specifc data NFT-FT. - -Call structure: "unFreezeSingleNFT" + "@" + nonce hex encoded + "@" + address hex encoded. - -Example: "unFreezeSingleNFT@05@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### wipeSingleNFT - -```rust - #[endpoint(wipeSingleNFT)] - fn wipe_single_token_for_address( - &self, - nonce: u64, - address: &ManagedAddress - ); -``` - -Endpoint that wipes specific data NFT-FT for a specific address. It will utilize the token issued previously and owned by the smart contract and the nonce of the data NFT-FT. The token manager may wipe out the tokens held by a frozen account, reducing the supply - -Call structure: "wipeSingleNFT" + "@" + nonce hex encoded + "@" + address hex encoded. - -Example: "wipeSingleNFT@05@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c" - -#### setIsPaused - -```rust - #[endpoint(setIsPaused)] - fn set_is_paused( - &self, - is_paused: bool - ); -``` - -Endpoint that sets the value of the pause variable. This variable is used to determined whether minting Data NFT-FT is activated or not. - -Call structure: "setIsPaused" + "@" + is_paused hex encoded. - -Example: "setIsPaused@00" - -#### setAntiSpamTax - -```rust - #[endpoint(setAntiSpamTax)] - fn set_anti_spam_tax( - &self, - token_id: &EgldOrEsdtTokenIdentifier, - tax: BigUint - ); -``` - -Endpoint that sets the token identifier and the tax value that will be used as a price for minting Data NFT-FTs, it will act also as an anti spam tax. The endpoint can take any token identifier, but be aware that diferent tokens have diferent decimals. - -Call structure: "setAntiSpamTax" + "@" + token_id hex encoded + "@" + tax hex encoded. - -Example: "setAntiSpamTax@45474c44@015af1d78b58c40000" - -#### setWhiteListEnabled - -```rust - #[endpoint(setWhiteListEnabled)] - fn set_whitelist_enabled( - &self, - is_enabled: bool - ); -``` - -Endpoint that sets wether the contract lets only whitelisted addresses to mint or not. If the contract has whitelist disabled, all addresses can mint. - -Call structure: "setWhiteListEnabled" + "@" + is_enabled hex encoded. - -Example: "setWhiteListEnabled@01" - -#### setWhiteListSpots - -```rust - #[endpoint(setWhiteListSpots)] - fn set_whitelist_spots( - &self, - whitelist: MultiValueEncoded - ); -``` - -Endpoint that sets whitelist spots for given addresses. The argument can take a list of addreses. - -Call structure: "setWhiteListSpots" + "@" + address1 hex encoded -(can add as many addresses as needed). - -Example: "setWhitelistSpots@8bc1730b9afdd4546a039c3baa043f37525822100e04cfc986b6955e05cbf101" - -#### removeWhiteListSpots - -```rust - #[endpoint(removeWhiteListSpots)] - fn remove_whitelist_spots( - &self, - whitelist: MultiValueEncoded - ); -``` - -Endpoint that removes whitelist spots for given addresses. The argument can take a list of addreses. - -Call structure: "removeWhiteListSpots" + "@" + address1 hex encoded -(can add as many addresses as needed). - -Example: "removeWhiteListSpots@8bc1730b9afdd4546a039c3baa043f37525822100e04cfc986b6955e05cbf101" - -#### setRoyaltiesLimits - -```rust - #[endpoint(setRoyaltiesLimits)] - fn set_royalties_limits( - &self, - min_royalties: BigUint, - max_royalties: BigUint - ); -``` - -Endpoint that sets the minimum and maximum royalties that can be set by the users when minting a Data NFT-FT. - -Call structure: "setRoyaltiesLimits" + "@" + min_royalties hex encoded + "@" + max_royalties hex encoded. - -Example: "setRoyaltiesLimits@00@01f40" - -#### setMaxSupply - -```rust - #[endpoint(setMaxSupply)] - fn set_max_supply( - &self, - max_supply: BigUint - ); -``` - -Endpoint that sets the value of the max supply variable. This variable is used to determined the maximum supply of the Data NFT-FTs an user can mint. - -Call structure: "setMaxSupply" + "@" + max_supply hex encoded. - -Example: "setMaxSupply@05" - -### Public endpoints - -#### mint - -```rust - #[payable("*")] - #[endpoint(mint)] - fn mint_token( - &self, - name: ManagedBuffer, - media: ManagedBuffer, - data_marshal: ManagedBuffer, - data_stream: ManagedBuffer, - data_preview: ManagedBuffer, - royalties: BigUint, - supply: BigUint, - title: ManagedBuffer, - description: ManagedBuffer - ); -``` - -Endpoint that allows anyone to mint Data NFT-FTs. The endpoint takes as arguments the name (NFT-FT name), media (NFT-FT media url), data_marshal (marshal service url), data_stream (data stream url), data_preview (data preview url), royalties (royalties value between min_royalties and max_royalties), supply (supply value between 1 and max_supply), title (longer title describing the data NFT-FT dataset) and description (Dataset description). - -Call structure for EGLD payment: "mint" + "@" + name hex encoded + "@" + media hex encoded + "@" + data_marshal hex encoded + "@" + data_stream hex encoded + "@" + data_preview hex encoded + "@" + royalties hex encoded + "@" + supply hex encoded + "@" + title hex encoded + "@" + description hex encoded. - -Example: "mint@4d792044617461204e4654@68747470733a2f2f69746865756d2e696f2f746573742f746573742f746573742f746573742f6d65646961@68747470733a2f2f69746865756d2e696f2f746573742f746573742f746573742f746573742f6d65646961@68747470733a2f2f69746865756d2e696f2f746573742f746573742f746573742f746573742f6d65646961@68747470733a2f2f69746865756d2e696f2f746573742f746573742f746573742f746573742f6d65646961@3c@05@4e46542d4654205469746c65@4e46542d4654204465736372697074696f6e" - -Call structure for ESDT payment: "ESDTTransfer" + "@" + token to send hex encoded + "@" + number of tokens to send hex encoded + "@" + "mint" hex encoded + "@" + name hex encoded + "@" + media hex encoded + "@" + data_marshal hex encoded + "@" + data_stream hex encoded + "@" + data_preview hex encoded + "@" + royalties hex encoded + "@" + supply hex encoded + "@" + title hex encoded + "@" + description hex encoded. - -Example: "ESDTTransfer@49544845554d2d613631333137@015af1d78b58c40000@6d696e74@53616d706c65546f6b656e4e616d65@68747470733a2f2f697066732e696f2f697066732f62616679726569647835367968706f7371626e6b616432767970363734713574776a637666356a67767473626579686f6366346b6a657835776f34@68747470733a2f2f69746865756d6170692e636f6d2f646465782f646174616d61727368616c2f76312f73657276696365732f67656e6572617465@68747470733a2f2f69746865756d2d7265736f75726365732e73332e61702d736f757468656173742d322e616d617a6f6e6177732e636f6d2f6a736f6e2f54484f525f45636f47505f52616365312e637376@68747470733a2f2f69746865756d2d7265736f75726365732e73332e61702d736f757468656173742d322e616d617a6f6e6177732e636f6d2f6a736f6e2f54484f525f45636f47505f52616365312e637376@@01@53616d706c65205469746c65@53616d706c65204465736372697074696f6e" - -#### burn - -```rust - #[payable("*")] - #[endpoint(burn)] - fn burn_token(&self); -``` - -Endpoint that allows anyone to burn the sent amount of Data NFT-FTs. - -Call structure: "ESDTTransfer" + "@" + NFT-FT token identifier hex encoded + "@" + token nonce hex encoded + "@" + number of tokens to burn hex encoded + "@" + contract address hex encoded + "@" +"burn" hex encoded. - -Example: "ESDTNFTTransfer@4e465446542d373736336637@01@1e@00000000000000000500c72532eb1c8f5e32034b46b5041babade020fdefd5fd@6275726e" - -### withdrawal address endpoints - -#### withdraw - -```rust - #[endpoint(withdraw)] - fn withdraw(&self, - token_identifier: &EgldOrEsdtTokenIdentifier, - nonce: u64, - amount: BigUint - ); -``` - -Endpoint that allows the withdrawal address to withdraw funds from the smart contract. The endpoint takes as arguments the token identifier, the nonce of the token and the amount to withdraw. - -Call structure: "withdraw" + "@" + token_identifier hex encoded + "@" + nonce hex encoded + "@" + amount hex encoded. - -Example: "withdraw@4e465446542d373736336637@00@91b77e5e5d9a0000" - -### Views - -#### getUserDataOut - -```rust - #[view(getUserDataOut)] - fn get_user_data_out(&self, - address: ManagedAddress, - tax_token: &EsdtTokenIdentifier - ); -``` - -Main view of the contract. Receives an address and a token identifier as arguments and returns a structure that contains all the data needed by the frontend in order to limit the user from wrongly interacting with the smart contract. The structure contains the following fields: - -- **anti_spam_tax_value**: the value of the anti spam tax for the given token identifier -- **is_paused**: a boolean that indicates if the contract is paused or not -- **max_royalties**: the maximum royalties value that can be set by the user -- **min_royalties**: the minimum royalties value that can be set by the user -- **max_supply**: the maximum supply value that can be set by the user -- **mint_time_limit**: the time limit for minting a data NFT-FT -- **last_mint_time**: the last time a data NFT-FT was minted by the given address -- **whitelist_enabled**: a boolean that indicates if the whitelist is enabled or not -- **is_whitelisted**: a boolean that indicates if the given address is whitelisted or not -- **minted_per_user**: total number of minted data NFT-FTs for given address -- **total_minted**: the total number of minted data NFT-FTs -- **frozen**: boolean that indicates if the given address is frozen or not for the entire collection -- **frozen_nonces**: a list of frozen nonces (of the smart contract token) for the given address +See `devnet.snippets.sh` for list of available endpoints for user testing. ## Development -This smart contract aims to offer the Elrond community an audited NFT minter smart contract that is easy to use, well documented and secure. +This smart contract aims to offer the MultiversX community an audited NFT minter smart contract that is easy to use, well documented and secure. ### Setting up dev environment (project development bootstrap) + how to build (and upgrade) -- Uses `multiversx-sc-* 0.39.4` (starting v2.0.0, we used 0.45.1) SDK libs (see Cargo.toml) -- Building requires minimum **mxpy 6.1.1** (starting v2.0.0, we used mxpy 8.1.2). Check version using `mxpy --version` -- To build the project, requires minimum Rust version `1.69.0-nightly` (staring v2.0.0, we used 1.75.0-nightly). Check your Rust version by running `rustc --version`. To update your Rust, run `rustup update`. To set to nightly run `rustup default nightly` +- Uses `multiversx-sc-* 0.39.4` (In v3.0.0, we used 0.47.5) SDK libs (see Cargo.toml) +- Building requires minimum **mxpy 6.1.1** (In v2.0.0, we used mxpy 9.5.1). Check version using `mxpy --version` +- To build the project, requires minimum Rust version `1.76.0-nightly` (In v3.0.0, we used 1.76.0-nightly). Check your Rust version by running `rustc --version`. To update your Rust, run `rustup update`. To set to nightly run `rustup default nightly`. Note that `mxpy deps install rust --overwrite` also brings in it's own compatible rust version so running `rustup default nightly` might have a higher rust version than what is used via `mxpy deps install rust --overwrite`. - After you make sure you have the minimum Rust version you can then begin development. After you clone repo and before you run build, deploy or run the tests - follow these steps (most likely only needed the 1st time) - [Upgrades] Note that when we upgrade smart contract, we should again follow the steps below too as lib version may have changed (but for upgrade I skipped the rustup default nightly cmd and did the others) @@ -484,14 +64,9 @@ The Smart Contract is structured in 6 files: The tests are located in the tests folder, in the rust_tests file. In order to run the tests one can use the command: ```shell - cargo test --package datanftmint --test blackbox_tests -- --nocapture // [NOT DONE YET] - cargo test --package datanftmint --test whitebox_tests -- --nocapture // [NOT DONE YET] - - cargo test --package datanftmint --test rust_tests -- --nocapture // [OLD WAY, will work!] + cargo test ``` -- Note that in Oct 2023 we moved the Claim contract to blackbox and whitebox testing as recommended by the multiversX dev docs. We have HAVE NOT upgraded this yet for this smart contract so you need to use the OLD WAY - Another way of running the tests is by using the rust-analyzer extension in Visual Studio Code, which is also very helpful for MultiversX Smart Contract development. If one has the extension installed, they can go open and go to the top of the rust_tests file and click the Run Tests button. Note: In order to run the tests, one has to use the rust nightly version. One can switch to the nightly version by using: @@ -533,7 +108,7 @@ After deployment, one can interact with the smart contract and test its function **Step 2 (Final build + Code Hash):** Once the main commit is locked in, we can then produce the code hash and build to deploy to devnet 1st (for final testing) and then to mainnet (after sending the code hash to the auditor) -1. Make sure your mxpy version is >= 6 (starting v2.0.0, we used mxpy 8.1.2). +1. Make sure your mxpy version is >= 6 (In v3.0.0, we used mxpy 9.5.1). 2. If Cargo.lock is in gitignore, remove it, build the contract and make a new commit. Otherwise this step can be skipped. (see Step 1 and repeat if needed) 3. Run the following in the root of the repository (run the latest Docker client in your computer. Used `Docker Desktop 4.18.0 (104112) on MacOX 12.6`): @@ -541,7 +116,7 @@ Once the main commit is locked in, we can then produce the code hash and build t Note that if you already have a output-docker from a previous build and deploy then delete this folder. -Also note that if you are upgrading you may need to use a newer docker `sdk-rust-contract-builder` version. You can see the tags here https://hub.docker.com/r/multiversx/sdk-rust-contract-builder/tags. Starting v2.0.0, we used v5.3.0 for the build to upgrade to. We tested this on devnet before doing it on mainnet. +Also note that if you are upgrading you may need to use a newer docker `sdk-rust-contract-builder` version. You can see the tags here https://hub.docker.com/r/multiversx/sdk-rust-contract-builder/tags. In v2.0.0, we used v5.3.0 and for v3.0.0, we used v6.1.1 for the build to upgrade to. We tested this on devnet before doing it on mainnet. This process may take some time. After it's done you should see "Docker build ran successfully!". An output-docker folder will be created containing the WASM files built in a reproducible way and artifacts.json containing the code hash of the WASM files. @@ -561,7 +136,3 @@ We should have got this final clear in Step 2, but we still do a final check her ## Contributing Feel free the contact the development team if you wish to contribute or if you have any questions. If you find any issues, please report them in the Issues sections of the repository. You can also create your own pull requests which will be analyzed by the team. - -``` - -``` diff --git a/interaction/devnet.snippets.sh b/interaction/devnet.snippets.sh index 290f92d..e678433 100644 --- a/interaction/devnet.snippets.sh +++ b/interaction/devnet.snippets.sh @@ -394,6 +394,7 @@ mintTokenUsingEsdt(){ # $9 = supply # $10 = title # $11 = description + # $12 = lock period (added v3.0.0) method="0x$(echo -n 'mint' | xxd -p -u | tr -d '\n')" name="0x$(echo -n ${2} | xxd -p -u | tr -d '\n')" @@ -408,9 +409,9 @@ mintTokenUsingEsdt(){ mxpy --verbose contract call $ADDRESS \ --recall-nonce \ --pem=${USER} \ - --gas-limit=100000000 \ + --gas-limit=30000000 \ --function "ESDTTransfer" \ - --arguments ${TOKEN_HEX} $1 $method $name $media $metadata $data_marshal $data_stream $data_preview $7 $8 $title $description \ + --arguments ${TOKEN_HEX} $1 $method $name $media $metadata $data_marshal $data_stream $data_preview $8 $9 $title $description $12 \ --proxy ${PROXY} \ --chain ${CHAIN_ID} \ --send || return @@ -441,7 +442,7 @@ mintTokenUsingEgld(){ mxpy --verbose contract call ${ADDRESS} \ --recall-nonce \ --pem=${WALLET} \ - --gas-limit=10000000 \ + --gas-limit=30000000 \ --value=${1} \ --function "mint" \ --arguments $name $media $data_marshal $data_stream $data_preview $7 $8 $title $description \ @@ -500,3 +501,20 @@ withdraw(){ --chain ${CHAIN_ID} \ --send || return } + +# v3.0.0 +setBondContractAddress(){ + # $1 = bond contract address + + bond_contract_address="0x$(mxpy wallet bech32 --decode ${1})" + + mxpy --verbose contract call ${ADDRESS} \ + --recall-nonce \ + --pem=${WALLET} \ + --gas-limit=6000000 \ + --function "setBondContractAddress" \ + --arguments $bond_contract_address \ + --proxy ${PROXY} \ + --chain ${CHAIN_ID} \ + --send || return +} diff --git a/interaction/mainnet.snippets.sh b/interaction/mainnet.snippets.sh index 1e21a9c..9b9e049 100644 --- a/interaction/mainnet.snippets.sh +++ b/interaction/mainnet.snippets.sh @@ -394,6 +394,7 @@ mintTokenUsingEsdtMainnet(){ # $9 = supply # $10 = title # $11 = description + # $12 = lock period (added v3.0.0) method="0x$(echo -n 'mint' | xxd -p -u | tr -d '\n')" name="0x$(echo -n ${2} | xxd -p -u | tr -d '\n')" @@ -409,7 +410,7 @@ mintTokenUsingEsdtMainnet(){ --recall-nonce \ --gas-limit=100000000 \ --function "ESDTTransfer" \ - --arguments ${TOKEN_HEX} $1 $method $name $media $metadata $data_marshal $data_stream $data_preview $7 $8 $title $description \ + --arguments ${TOKEN_HEX} $1 $method $name $media $metadata $data_marshal $data_stream $data_preview $7 $8 $title $description $12 \ --proxy ${PROXY} \ --chain ${CHAIN_ID} \ --ledger \ @@ -503,3 +504,21 @@ withdrawMainnet(){ --ledger-address-index 0 \ --send || return } + +# v3.0.0 +setBondContractAddressMainnet(){ + # $1 = bond contract address + + bond_contract_address="0x$(mxpy wallet bech32 --decode ${1})" + + mxpy --verbose contract call ${ADDRESS} \ + --recall-nonce \ + --gas-limit=6000000 \ + --function "setBondContractAddress" \ + --arguments $bond_contract_address \ + --proxy ${PROXY} \ + --chain ${CHAIN_ID} \ + --ledger \ + --ledger-address-index 0 \ + --send || return +} diff --git a/meta/Cargo.lock b/meta/Cargo.lock index cc80c92..29d6b18 100644 --- a/meta/Cargo.lock +++ b/meta/Cargo.lock @@ -27,18 +27,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "0.7.20" @@ -48,12 +36,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "anstream" version = "0.6.4" @@ -110,9 +92,9 @@ checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atty" @@ -160,9 +142,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bstr" @@ -235,7 +217,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -321,14 +303,14 @@ dependencies = [ [[package]] name = "datanftmint" -version = "2.0.0" +version = "3.0.0" dependencies = [ "multiversx-sc", ] [[package]] name = "datanftmint-meta" -version = "2.0.0" +version = "3.0.0" dependencies = [ "datanftmint", "multiversx-sc", @@ -503,10 +485,6 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "heck" @@ -731,12 +709,11 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11b51d6a2ab0218585ed58e100c5ac2218de09490fbfc4243b5ecd0ca7f5cbc" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ - "bitflags 1.3.2", - "hashbrown", + "bitflags 2.4.2", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -745,9 +722,9 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327b0ad1c3477cab0d7c84391439ba302238f738ef3c6e1fcd18e247fba84875" +checksum = "1da6db65170105c9495848c5e4ba388abb1f9201ff2ca362056c9328f36b7760" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", @@ -756,34 +733,34 @@ dependencies = [ [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f444038e0043b8eda816b26952479c2aca3c4a643580f4337f71fb362a586db5" +checksum = "631c4d4b37fc94659c8d6cf559c21b68c68899095201de2e1b779fccad7b0b03" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.86", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784f0fc505806102fe6f808b368e12fcb13096dd73c5678f09c5663230724d6f" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.86", + "syn", ] [[package]] name = "multiversx-sc-meta" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3fad2491d11c6edf3fe131696be31743dc568457c013b2c256e56376da294b" +checksum = "3522f14ef47b1516a6635e86e0c19acffd8d328eb194a90c29b05d09a22c5296" dependencies = [ "clap", "colored", @@ -797,10 +774,11 @@ dependencies = [ "reqwest", "ruplacer", "rustc_version", + "semver", "serde", "serde_json", "toml", - "wasmparser 0.116.1", + "wasmparser 0.121.2", "wasmprinter", "zip", ] @@ -834,9 +812,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -855,9 +833,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -893,7 +871,7 @@ version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -910,7 +888,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -963,18 +941,18 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1089,7 +1067,7 @@ version = "0.38.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -1145,9 +1123,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.6" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" @@ -1166,7 +1144,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -1244,20 +1222,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1455,12 +1422,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "url" version = "2.5.0" @@ -1484,12 +1445,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "walkdir" version = "2.3.2" @@ -1537,7 +1492,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn", "wasm-bindgen-shared", ] @@ -1571,7 +1526,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1584,9 +1539,9 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasmparser" -version = "0.116.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", "semver", @@ -1594,10 +1549,11 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.118.1" +version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ + "bitflags 2.4.2", "indexmap", "semver", ] @@ -1804,26 +1760,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "zerocopy" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "zip" version = "0.6.6" diff --git a/meta/Cargo.toml b/meta/Cargo.toml index 43595c7..21ab852 100644 --- a/meta/Cargo.toml +++ b/meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "datanftmint-meta" -version = "2.0.0" +version = "3.0.0" edition = "2021" publish = false authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum"] @@ -10,7 +10,7 @@ authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum" path = ".." [dependencies.multiversx-sc] -version = "0.45.1" +version = "0.47.5" [dependencies.multiversx-sc-meta] -version = "0.45.1" +version = "0.47.5" 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/errors.rs b/src/errors.rs index e7631da..53a6896 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -36,4 +36,5 @@ 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"; +pub const ERR_WRONG_BOND_PERIOD: &str = "Wrong bond period"; diff --git a/src/events.rs b/src/events.rs index b52f8d3..76a4a2c 100644 --- a/src/events.rs +++ b/src/events.rs @@ -128,11 +128,15 @@ pub trait EventsModule { #[indexed] amount: &BigUint, #[indexed] token: &EgldOrEsdtTokenIdentifier, #[indexed] price: &BigUint, + #[indexed] bond_amount: &BigUint, ); #[event("setWithdrawalAddress")] fn set_withdrawal_address_event(&self, #[indexed] address: &ManagedAddress); + #[event("setBondContractAddress")] + fn set_bond_contract_address_event(&self, #[indexed] address: &ManagedAddress); + #[event("withdrawTokens")] fn withdraw_tokens_event( &self, diff --git a/src/lib.rs b/src/lib.rs index 21a9b6c..2be9e56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,12 +7,13 @@ 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_WRONG_AMOUNT_OF_PAYMENT, + ERR_ISSUE_COST, ERR_NOT_IN_WHITELIST, ERR_WHITELIST_IS_EMPTY, ERR_WRONG_AMOUNT_OF_FUNDS, + ERR_WRONG_BOND_PERIOD, }, storage::DataNftAttributes, }; +pub mod bonding_proxy; pub mod callbacks; pub mod collection_management; pub mod errors; @@ -21,6 +22,7 @@ pub mod nft_mint_utils; pub mod requirements; pub mod storage; pub mod views; + #[multiversx_sc::contract] pub trait DataNftMint: storage::StorageModule @@ -30,6 +32,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] @@ -50,6 +53,11 @@ pub trait DataNftMint: self.set_max_supply_event(&self.max_supply().get()); } + #[upgrade] + fn upgrade(&self) { + self.is_paused().set(true); + } + // Endpoint used by the owner in the first place to initialize the contract with all the data needed for the SFT token creation #[only_owner] #[payable("EGLD")] @@ -77,6 +85,7 @@ pub trait DataNftMint: self.set_mint_time_limit_event(&mint_time_limit); self.mint_time_limit().set(mint_time_limit); self.treasury_address().set(&treasury_address); + // Collection issuing self.send() .esdt_system_sc_proxy() @@ -138,6 +147,7 @@ pub trait DataNftMint: supply: BigUint, title: ManagedBuffer, description: ManagedBuffer, + lock_period_sec: u64, ) -> DataNftAttributes { self.require_ready_for_minting_and_burning(); require!(!data_stream.is_empty(), ERR_DATA_STREAM_IS_EMPTY); @@ -155,11 +165,28 @@ pub trait DataNftMint: self.require_minting_is_allowed(&caller, current_time); self.last_mint_time(&caller).set(current_time); - let payment = self.call_value().egld_or_single_esdt(); + let mut payment = self.call_value().egld_or_single_esdt(); let price = self.anti_spam_tax(&payment.token_identifier).get(); - // The contract will panic if the user tries to use a token which is has not been set as buyable by the owner. - self.require_value_is_positive(&payment.amount); - require!(&payment.amount == &price, ERR_WRONG_AMOUNT_OF_PAYMENT); + + let treasury_address = self.treasury_address().get(); + + 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 + ); + + payment.amount -= &price; + + 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) @@ -179,7 +206,13 @@ pub trait DataNftMint: let token_identifier = self.token_id().get_token_id(); - self.mint_event(&caller, &one_token, &payment.token_identifier, &price); + self.mint_event( + &caller, + &one_token, + &payment.token_identifier, + &price, + &payment.amount, + ); let nonce = self.send().esdt_nft_create( &token_identifier, @@ -191,18 +224,17 @@ pub trait DataNftMint: &self.create_uris(media, metadata), ); + self.send_bond( + &caller, + token_identifier.clone(), + nonce, + lock_period_sec, + payment, + ); + self.send() .direct_esdt(&caller, &token_identifier, nonce, &supply); - let treasury_address = self.treasury_address().get(); - - self.send().direct( - &treasury_address, - &payment.token_identifier, - payment.token_nonce, - &payment.amount, - ); - attributes } @@ -243,15 +275,6 @@ pub trait DataNftMint: self.is_paused().set(is_paused); } - // Endpoint that will be used by privileged address to set the anti spam tax for a specific token identifier. - #[endpoint(setAntiSpamTax)] - fn set_anti_spam_tax(&self, token_id: EgldOrEsdtTokenIdentifier, tax: BigUint) { - let caller = self.blockchain().get_caller(); - self.require_is_privileged(&caller); - self.set_anti_spam_tax_event(&token_id, &tax); - self.anti_spam_tax(&token_id).set(tax); - } - // Endpoint that will be used by the owner and privileged address to change the whitelist enable value. #[endpoint(setWhiteListEnabled)] fn set_whitelist_enabled(&self, is_enabled: bool) { @@ -261,6 +284,15 @@ pub trait DataNftMint: self.whitelist_enabled().set(is_enabled); } + // Endpoint that will be used by privileged address to set the anti spam tax for a specific token identifier. + #[endpoint(setAntiSpamTax)] + fn set_anti_spam_tax(&self, token_id: EgldOrEsdtTokenIdentifier, tax: BigUint) { + let caller = self.blockchain().get_caller(); + self.require_is_privileged(&caller); + self.set_anti_spam_tax_event(&token_id, &tax); + self.anti_spam_tax(&token_id).set(tax); + } + // Endpoint that will be used by the owner and privileged address to set whitelist spots. #[endpoint(setWhiteListSpots)] fn set_whitelist_spots(&self, whitelist: MultiValueEncoded) { @@ -327,6 +359,15 @@ pub trait DataNftMint: self.administrator().set(&administrator); } + // Endpoint to set the bonding contract address + #[only_owner] + #[endpoint(setBondContractAddress)] + fn set_bond_contract_address(&self, bond_contract_address: ManagedAddress) { + self.set_bond_contract_address_event(&bond_contract_address); + self.bond_contract_address().set(&bond_contract_address); + } + + // Endpoint to set the withdraw address to collect 3rd party royalties into #[only_owner] #[endpoint(setWithdrawalAddress)] fn set_withdrawal_address(&self, withdrawal_address: ManagedAddress) { @@ -334,7 +375,8 @@ pub trait DataNftMint: self.withdrawal_address().set(&withdrawal_address); } - #[endpoint(withdraw)] // smart contract must be payable to receive royalties + // Endpoint for approved withdrawer to withdraw 3rd party royalties + #[endpoint(withdraw)] fn withdraw(&self, token_identifier: EgldOrEsdtTokenIdentifier, nonce: u64, amount: BigUint) { let caller = self.blockchain().get_caller(); @@ -351,7 +393,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); } } } diff --git a/src/requirements.rs b/src/requirements.rs index 377e1e3..de5fdc3 100644 --- a/src/requirements.rs +++ b/src/requirements.rs @@ -26,9 +26,15 @@ pub trait RequirementsModule: crate::storage::StorageModule { if self.treasury_address().is_empty() { is_mint_ready = false; } + if self.bond_contract_address().is_empty() { + is_mint_ready = false; + } 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); } @@ -97,22 +103,22 @@ pub trait RequirementsModule: crate::storage::StorageModule { // Checks whether the URL passed is valid (characters, starts with https://) fn require_url_is_valid(&self, url: &ManagedBuffer) { - self.require_url_is_adequate_length(url); - - // Define a closure to perform the URL validation - let validation_closure = |url_bytes: &[u8]| { - let starts_with: &[u8] = b"https://"; - - for i in 0..starts_with.len() { - require!(url_bytes[i] == starts_with[i], ERR_NOT_URL); - } - - for i in 0..url_bytes.len() { - require!( - url_bytes[i] > 32 && url_bytes[i] < 127, - ERR_URL_INVALID_CHARACTERS - ) - } + self.require_url_is_adequate_length(url); + + // Define a closure to perform the URL validation + let validation_closure = |url_bytes: &[u8]| { + let starts_with: &[u8] = b"https://"; + + for i in 0..starts_with.len() { + require!(url_bytes[i] == starts_with[i], ERR_NOT_URL); + } + + for i in 0..url_bytes.len() { + require!( + url_bytes[i] > 32 && url_bytes[i] < 127, + ERR_URL_INVALID_CHARACTERS + ) + } }; // Use the with_buffer_contents function to apply the closure diff --git a/src/storage.rs b/src/storage.rs index 1510080..d850da3 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -107,4 +107,8 @@ pub trait StorageModule { #[view(getAdministrator)] #[storage_mapper("administrator")] fn administrator(&self) -> SingleValueMapper; + + #[view(getBondContractAddress)] + #[storage_mapper("bond_contract_address")] + fn bond_contract_address(&self) -> SingleValueMapper; } diff --git a/src/views.rs b/src/views.rs index d9969e4..953d3d8 100644 --- a/src/views.rs +++ b/src/views.rs @@ -31,7 +31,7 @@ pub trait ViewsModule: crate::storage::StorageModule { tax_token: &EgldOrEsdtTokenIdentifier, ) -> UserDataOut { { - let anti_spam_tax_value = self.anti_spam_tax(tax_token).get(); //if it returns 0 the token is not supported + let anti_spam_tax_value = self.anti_spam_tax(tax_token).get(); //if it returns 0 the token is not supported or it requires only bondAmount to be sent let is_paused = self.is_paused().get(); let max_royalties = self.max_royalties().get(); let min_royalties = self.min_royalties().get(); 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), + ), + )); +} 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/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)), + ); +} 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")), + ); +} diff --git a/tests/endpoints/mint.rs b/tests/endpoints/mint.rs new file mode 100644 index 0000000..c7887e5 --- /dev/null +++ b/tests/endpoints/mint.rs @@ -0,0 +1,533 @@ +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, + 0u64, + Some(TxExpect::user_error("str:Wrong bond period")), + ); + + 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", + "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: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( + 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), + ), + ), + ); +} 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; 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"), + )); +} 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; 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/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); +} diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index ad5d1e1..3288287 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -2,29 +2,11 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" @@ -34,19 +16,13 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "datanftmint" -version = "2.0.0" +version = "3.0.0" dependencies = [ "multiversx-sc", ] @@ -65,16 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -89,12 +55,11 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11b51d6a2ab0218585ed58e100c5ac2218de09490fbfc4243b5ecd0ca7f5cbc" +checksum = "0f2a40b8535885488f1449ba6f03e05e6013c2ff73c89c54f94dcdc0af7c8084" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", @@ -103,9 +68,9 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327b0ad1c3477cab0d7c84391439ba302238f738ef3c6e1fcd18e247fba84875" +checksum = "1da6db65170105c9495848c5e4ba388abb1f9201ff2ca362056c9328f36b7760" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", @@ -113,34 +78,34 @@ dependencies = [ [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.2" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f444038e0043b8eda816b26952479c2aca3c4a643580f4337f71fb362a586db5" +checksum = "631c4d4b37fc94659c8d6cf559c21b68c68899095201de2e1b779fccad7b0b03" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.86", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784f0fc505806102fe6f808b368e12fcb13096dd73c5678f09c5663230724d6f" +checksum = "73567b0b79730b4f6000c2fac4a21ea7ba8c8b12aa32901dd8ff10ccb90cfd79" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.86", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.45.1" +version = "0.47.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5afb8b8cc380eabd82dc8f9b02afbab3dce16fc2b5de1dbc601fcfcf261278ba" +checksum = "e7e6e0330769b8b46966c5fc59fd13bd95a0d5b330cf0aa55c0403dbb911fa71" dependencies = [ "multiversx-sc", ] @@ -156,33 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] -[[package]] -name = "once_cell" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" - [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -199,26 +158,15 @@ 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 = "syn" -version = "1.0.86" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "2.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -230,35 +178,3 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 32ec7fe..69e3da5 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -19,12 +19,13 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false [dependencies.datanftmint] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.45.1" +version = "0.47.5" [workspace] members = ["."] diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 3973788..0fc1b9a 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -5,14 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 43 +// Endpoints: 48 // Async Callback: 1 -// Total number of exported functions: 45 +// Total number of exported functions: 50 #![no_std] - -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. +#![allow(internal_features)] #![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); @@ -22,20 +20,22 @@ multiversx_sc_wasm_adapter::endpoints! { datanftmint ( init => init + upgrade => upgrade initializeContract => initialize_contract setLocalRoles => set_local_roles mint => mint_token burn => burn_token setTreasuryAddress => set_treasury_address setIsPaused => set_is_paused - setAntiSpamTax => set_anti_spam_tax setWhiteListEnabled => set_whitelist_enabled + setAntiSpamTax => set_anti_spam_tax setWhiteListSpots => set_whitelist_spots removeWhiteListSpots => remove_whitelist_spots setMintTimeLimit => set_mint_time_limit setRoyaltiesLimits => set_royalties_limits setMaxSupply => set_max_supply setAdministrator => set_administrator + setBondContractAddress => set_bond_contract_address setWithdrawalAddress => set_withdrawal_address withdraw => withdraw getTokenId => token_id @@ -57,6 +57,7 @@ multiversx_sc_wasm_adapter::endpoints! { isWhiteListEnabled => whitelist_enabled rolesAreSet => roles_are_set getAdministrator => administrator + getBondContractAddress => bond_contract_address getUserDataOut => get_user_data_out pause => pause_collection unpause => unpause_collection @@ -65,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 ) }