From f54deab4bf2537df306d1394eeb3eff457f48707 Mon Sep 17 00:00:00 2001 From: mintthemoon Date: Mon, 12 Aug 2024 13:08:08 -0400 Subject: [PATCH 1/3] cargo updates, bump dependency versions, update code and tests (wip) --- .cargo/{config => config.toml} | 0 Cargo.lock | 1111 +++++++++------ Cargo.toml | 17 +- .../.cargo/{config => config.toml} | 0 contracts/cw2981-royalties/Cargo.toml | 2 - contracts/cw2981-royalties/src/lib.rs | 38 +- contracts/cw2981-royalties/src/query.rs | 2 +- .../cw721-base/.cargo/{config => config.toml} | 0 contracts/cw721-base/Cargo.toml | 2 - contracts/cw721-base/src/lib.rs | 8 +- .../.cargo/{config => config.toml} | 0 contracts/cw721-expiration/Cargo.toml | 2 - .../cw721-expiration/src/contract_tests.rs | 542 +++++--- contracts/cw721-expiration/src/lib.rs | 18 +- contracts/cw721-expiration/src/state.rs | 8 +- .../.cargo/{config => config.toml} | 0 contracts/cw721-fixed-price/Cargo.toml | 2 - contracts/cw721-fixed-price/src/contract.rs | 58 +- .../.cargo/{config => config.toml} | 0 contracts/cw721-metadata-onchain/Cargo.toml | 2 - contracts/cw721-metadata-onchain/src/lib.rs | 14 +- .../.cargo/{config => config.toml} | 0 contracts/cw721-non-transferable/Cargo.toml | 2 - .../.cargo/{config => config.toml} | 0 contracts/cw721-receiver-tester/Cargo.toml | 2 - packages/cw721/.cargo/{config => config.toml} | 0 packages/cw721/src/query.rs | 14 +- packages/cw721/src/state.rs | 26 +- packages/cw721/src/testing/contract_tests.rs | 389 +++--- packages/cw721/src/testing/multi_tests.rs | 1188 +---------------- packages/cw721/src/testing/unit_tests.rs | 250 +--- packages/cw721/src/traits.rs | 2 +- 32 files changed, 1446 insertions(+), 2253 deletions(-) rename .cargo/{config => config.toml} (100%) rename contracts/cw2981-royalties/.cargo/{config => config.toml} (100%) rename contracts/cw721-base/.cargo/{config => config.toml} (100%) rename contracts/cw721-expiration/.cargo/{config => config.toml} (100%) rename contracts/cw721-fixed-price/.cargo/{config => config.toml} (100%) rename contracts/cw721-metadata-onchain/.cargo/{config => config.toml} (100%) rename contracts/cw721-non-transferable/.cargo/{config => config.toml} (100%) rename contracts/cw721-receiver-tester/.cargo/{config => config.toml} (100%) rename packages/cw721/.cargo/{config => config.toml} (100%) diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/Cargo.lock b/Cargo.lock index c2c62afa7..d03c222d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,12 +13,157 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anyhow" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rayon", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", + "rayon", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "base16ct" version = "0.2.0" @@ -31,6 +176,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -43,6 +194,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "block-buffer" version = "0.9.0" @@ -67,6 +224,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" +[[package]] +name = "bnum" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" + [[package]] name = "byteorder" version = "1.5.0" @@ -75,9 +238,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cfg-if" @@ -91,36 +254,88 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "cosmwasm-core" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d905990ef3afb5753bb709dc7de88e9e370aa32bcc2f31731d4b533b63e82490" + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra 3.1.0", + "k256", + "rand_core 0.6.4", + "thiserror", +] + [[package]] name = "cosmwasm-crypto" -version = "1.5.5" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" +checksum = "5b2a7bd9c1dd9a377a4dc0f4ad97d24b03c33798cd5a6d7ceb8869b41c5d2f2d" dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "cosmwasm-core", "digest 0.10.7", "ecdsa", - "ed25519-zebra", + "ed25519-zebra 4.0.3", "k256", + "num-traits", + "p256", "rand_core 0.6.4", + "rayon", + "sha2 0.10.8", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-derive" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029910b409398fdf81955d7301b906caf81f2c42b013ea074fbd89720229c424" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "cosmwasm-schema" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7879036156092ad1c22fe0d7316efc5a5eceec2bc3906462a2560215f2a2f929" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" dependencies = [ - "cosmwasm-schema-derive", + "cosmwasm-schema-derive 1.5.7", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc0d4d85e83438ab9a0fea9348446f7268bc016aacfebce37e998559f151294" +dependencies = [ + "cosmwasm-schema-derive 2.1.3", "schemars", "serde", "serde_json", @@ -129,32 +344,66 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "cosmwasm-schema-derive" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf5c8adac41bb7751c050d7c4c18675be19ee128714454454575e894424eeef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "cosmwasm-std" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" dependencies = [ - "base64", - "bech32", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", + "base64 0.21.7", + "bech32 0.9.1", + "bnum 0.10.0", + "cosmwasm-crypto 1.5.7", + "cosmwasm-derive 1.5.7", "derivative", "forward_ref", "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.2", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cosmwasm-std" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51dec99a2e478715c0a4277f0dbeadbb8466500eb7dec873d0924edd086e77f1" +dependencies = [ + "base64 0.22.1", + "bech32 0.11.0", + "bnum 0.11.0", + "cosmwasm-core", + "cosmwasm-crypto 2.1.3", + "cosmwasm-derive 2.1.3", + "derive_more", + "hex", + "rand_core 0.6.4", + "schemars", + "serde", + "serde-json-wasm 1.0.1", "sha2 0.10.8", "static_assertions", "thiserror", @@ -169,6 +418,31 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -204,36 +478,62 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "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.74", +] + [[package]] name = "cw-address-like" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", ] [[package]] name = "cw-address-like" -version = "1.0.4" -source = "git+https://github.com/public-awesome/cw-plus-plus.git?rev=28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523#28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523" +version = "2.0.4" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 2.1.3", ] [[package]] name = "cw-multi-test" -version = "0.20.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" +checksum = "e0034bfb4c06dfc8b50f0b1a06c3fc0f2312a1bae568a97db65930de071288ba" dependencies = [ "anyhow", - "bech32", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", + "bech32 0.11.0", + "cosmwasm-std 2.1.3", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", "derivative", - "itertools 0.12.1", + "itertools 0.13.0", "prost 0.12.6", "schemars", "serde", @@ -247,9 +547,9 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", + "cw-address-like 1.0.4", "cw-ownable-derive 0.5.1", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -259,14 +559,13 @@ dependencies = [ [[package]] name = "cw-ownable" version = "0.6.0" -source = "git+https://github.com/public-awesome/cw-plus-plus.git?rev=28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523#28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like 1.0.4 (git+https://github.com/public-awesome/cw-plus-plus.git?rev=28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523)", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw-address-like 2.0.4", "cw-ownable-derive 0.6.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", "thiserror", ] @@ -284,7 +583,6 @@ dependencies = [ [[package]] name = "cw-ownable-derive" version = "0.6.0" -source = "git+https://github.com/public-awesome/cw-plus-plus.git?rev=28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523#28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523" dependencies = [ "proc-macro2", "quote", @@ -293,10 +591,10 @@ dependencies = [ [[package]] name = "cw-paginate-storage" -version = "2.4.2" -source = "git+https://github.com/DA0-DA0/dao-contracts.git#bb8224ef1285266f4c8f11448e361f66c6a7e879" +version = "2.5.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git#2cac217cdea0e47dc32e9c9363175980774585d6" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "serde", ] @@ -307,7 +605,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6cf70ef7686e2da9ad7b067c5942cd3e88dd9453f7af42f54557f8af300fb0" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "schemars", "serde", ] @@ -318,7 +616,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", "schemars", "serde", ] @@ -329,7 +627,18 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 1.5.7", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13360e9007f51998d42b1bc6b7fa0141f74feae61ed5fd1e5b0a89eec7b5de1" +dependencies = [ + "cosmwasm-std 2.1.3", "schemars", "serde", ] @@ -340,8 +649,8 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ae0b69fa7679de78825b4edeeec045066aa2b2c4b6e063d80042e565bb4da5c" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 0.15.1", "schemars", "semver", @@ -355,8 +664,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 0.16.0", "schemars", "semver", @@ -370,8 +679,8 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 1.1.2", "schemars", "semver", @@ -379,14 +688,27 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07dfee7f12f802431a856984a32bce1cb7da1e6c006b5409e3981035ce562dec" +dependencies = [ + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw2" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5abb8ecea72e09afff830252963cb60faf945ce6cef2c20a43814516082653da" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.15.1", "schemars", "serde", @@ -398,8 +720,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "schemars", "serde", @@ -411,8 +733,8 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 1.2.0", "schemars", "semver", @@ -420,15 +742,30 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b04852cd38f044c0751259d5f78255d07590d136b8a86d4e09efdd7666bd6d27" +dependencies = [ + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw-storage-plus 2.0.0", + "schemars", + "semver", + "serde", + "thiserror", +] + [[package]] name = "cw20" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" +checksum = "a42212b6bf29bbdda693743697c621894723f35d3db0d5df930be22903d0e27c" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw-utils 2.0.0", "schemars", "serde", ] @@ -437,10 +774,10 @@ dependencies = [ name = "cw2981-royalties" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", "cw-ownable 0.6.0", - "cw2 1.1.2", + "cw2 2.0.0", "cw721 0.19.0", "schemars", "serde", @@ -453,8 +790,8 @@ name = "cw721" version = "0.15.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.15.0#27ffdc6c24c2d173be6c677d04bec1420191184d" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 0.15.1", "schemars", "serde", @@ -466,8 +803,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 0.16.0", "schemars", "serde", @@ -478,8 +815,8 @@ name = "cw721" version = "0.16.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0#2cad1d3e15e0a34d466a0b51e02c58b82ebe5ecd" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 0.16.0", "schemars", "serde", @@ -490,8 +827,8 @@ name = "cw721" version = "0.17.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.17.0#c1ece555dded6cbcebba1d417ed2a18d47ca3c8a" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "schemars", "serde", @@ -502,8 +839,8 @@ name = "cw721" version = "0.18.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.18.0#177a993dfb5a1a3164be1baf274f43b1ca53da53" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-utils 1.0.3", "schemars", "serde", @@ -513,14 +850,14 @@ dependencies = [ name = "cw721" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", "cw-multi-test", "cw-ownable 0.6.0", "cw-paginate-storage", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", "cw721 0.16.0 (git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0)", "cw721-base 0.15.0", "cw721-base 0.16.0 (git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0)", @@ -538,8 +875,8 @@ name = "cw721-base" version = "0.15.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.15.0#27ffdc6c24c2d173be6c677d04bec1420191184d" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.15.1", "cw-utils 0.15.1", "cw2 0.15.1", @@ -555,8 +892,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "cw-utils 0.16.0", "cw2 0.16.0", @@ -571,8 +908,8 @@ name = "cw721-base" version = "0.16.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0#2cad1d3e15e0a34d466a0b51e02c58b82ebe5ecd" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-storage-plus 0.16.0", "cw-utils 0.16.0", "cw2 0.16.0", @@ -587,8 +924,8 @@ name = "cw721-base" version = "0.17.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.17.0#c1ece555dded6cbcebba1d417ed2a18d47ca3c8a" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-ownable 0.5.1", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -605,8 +942,8 @@ name = "cw721-base" version = "0.18.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.18.0#177a993dfb5a1a3164be1baf274f43b1ca53da53" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw-ownable 0.5.1", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -622,10 +959,10 @@ dependencies = [ name = "cw721-base" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", "cw-ownable 0.6.0", - "cw2 1.1.2", + "cw2 2.0.0", "cw721 0.19.0", "serde", ] @@ -634,12 +971,12 @@ dependencies = [ name = "cw721-expiration" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", "cw-multi-test", "cw-ownable 0.6.0", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", "cw721 0.19.0", "schemars", "serde", @@ -650,11 +987,11 @@ dependencies = [ name = "cw721-fixed-price" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", "cw20", "cw721 0.19.0", "prost 0.10.4", @@ -668,8 +1005,8 @@ name = "cw721-metadata-onchain" version = "0.16.0" source = "git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0#2cad1d3e15e0a34d466a0b51e02c58b82ebe5ecd" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 1.5.7", + "cosmwasm-std 1.5.7", "cw2 0.16.0", "cw721 0.16.0 (git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0)", "cw721-base 0.16.0 (git+https://github.com/CosmWasm/cw-nfts?tag=v0.16.0)", @@ -681,9 +1018,9 @@ dependencies = [ name = "cw721-metadata-onchain" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw2 2.0.0", "cw721 0.19.0", "schemars", "serde", @@ -693,10 +1030,10 @@ dependencies = [ name = "cw721-non-transferable" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", "cw721 0.19.0", "schemars", "serde", @@ -706,8 +1043,8 @@ dependencies = [ name = "cw721-receiver-tester" version = "0.19.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.1.3", + "cosmwasm-std 2.1.3", "cw-multi-test", "cw721-base 0.19.0", "schemars", @@ -736,6 +1073,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -757,17 +1115,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "dyn-clone" version = "1.0.17" @@ -788,14 +1135,23 @@ dependencies = [ "spki", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "signature", +] + [[package]] name = "ed25519-zebra" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ - "curve25519-dalek", - "hashbrown", + "curve25519-dalek 3.2.0", + "hashbrown 0.12.3", "hex", "rand_core 0.6.4", "serde", @@ -803,11 +1159,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-zebra" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519", + "hashbrown 0.14.5", + "hex", + "rand_core 0.6.4", + "sha2 0.10.8", + "zeroize", +] + [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -838,6 +1209,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -892,152 +1269,51 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", + "ahash 0.7.8", ] [[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" +name = "hashbrown" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", + "ahash 0.8.11", ] [[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.0" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", + "ahash 0.8.11", + "allocator-api2", ] [[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "icu_provider_macros" -version = "1.5.0" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", + "digest 0.10.7", ] [[package]] name = "idna" -version = "1.0.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "icu_normalizer", - "icu_properties", - "smallvec", - "utf8_iter", + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -1058,6 +1334,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1066,9 +1351,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -1085,10 +1370,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "litemap" -version = "0.7.3" +name = "memchr" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] [[package]] name = "once_cell" @@ -1102,6 +1415,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1118,11 +1449,29 @@ dependencies = [ "spki", ] +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1170,7 +1519,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.74", ] [[package]] @@ -1182,6 +1531,26 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -1197,6 +1566,26 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -1207,6 +1596,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1234,7 +1632,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.66", + "syn 2.0.74", ] [[package]] @@ -1259,9 +1657,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.206" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284" dependencies = [ "serde_derive", ] @@ -1275,15 +1673,24 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.206" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.74", ] [[package]] @@ -1294,16 +1701,17 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.74", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1342,12 +1750,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "spki" version = "0.7.3" @@ -1358,12 +1760,6 @@ dependencies = [ "der", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -1372,9 +1768,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1389,62 +1785,62 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.74", ] [[package]] -name = "tinystr" -version = "0.7.6" +name = "tinyvec" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ - "displaydoc", - "zerovec", + "tinyvec_macros", ] +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -1452,33 +1848,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "url" -version = "2.5.1" +name = "unicode-normalization" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", + "tinyvec", ] [[package]] -name = "utf16_iter" -version = "1.0.5" +name = "unicode-xid" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] -name = "utf8_iter" -version = "1.0.4" +name = "url" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -1487,60 +1886,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - -[[package]] -name = "yoke" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - -[[package]] -name = "zerofrom" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" -dependencies = [ - "zerofrom-derive", + "byteorder", + "zerocopy-derive", ] [[package]] -name = "zerofrom-derive" -version = "0.1.4" +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", - "synstructure", + "syn 2.0.74", ] [[package]] @@ -1548,25 +1911,17 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zerovec" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", + "zeroize_derive", ] [[package]] -name = "zerovec-derive" -version = "0.10.2" +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.74", ] diff --git a/Cargo.toml b/Cargo.toml index e1c27399c..3df62af04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = ["packages/*", "contracts/*"] [workspace.package] @@ -11,10 +12,10 @@ documentation = "https://docs.cosmwasm.com" rust-version = "1.78" [workspace.dependencies] -cosmwasm-schema = "^1.5" -cosmwasm-std = "^1.5" -cw2 = "^1.1" -cw20 = "^1.1" +cosmwasm-schema = "^2.1" +cosmwasm-std = "^2.1" +cw2 = "^2.0" +cw20 = "^2.0" cw721 = { version = "*", path = "./packages/cw721" } cw721-016 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.16.0", package = "cw721" } # needed for backwards compatibility and legacy migration cw721-base = { version = "*", path = "./contracts/cw721-base" } @@ -23,11 +24,11 @@ cw721-base-016 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.16.0" cw721-metadata-onchain-016 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.16.0", package = "cw721-metadata-onchain" } # needed for testing legacy migration cw721-base-017 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.17.0", package = "cw721-base" } # needed for testing legacy migration cw721-base-018 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.18.0", package = "cw721-base" } # needed for testing legacy migration -cw-multi-test = { version = "^0.20", features = ["cosmwasm_1_2"] } -cw-ownable = { git = "https://github.com/public-awesome/cw-plus-plus.git", rev = "28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523"} # TODO: switch to official https://github.com/larry0x/cw-plus-plus once merged +cw-multi-test = { version = "^2.1", features = ["cosmwasm_2_0"] } +cw-ownable = { path = "../cw-plus-plus/packages/ownable" } # TODO: switch to official https://github.com/larry0x/cw-plus-plus once merged cw-paginate-storage = { version = "^2.4", git = "https://github.com/DA0-DA0/dao-contracts.git" } -cw-storage-plus = "^1.1" -cw-utils = "^1.0" +cw-storage-plus = "^2.0" +cw-utils = "^2.0" schemars = "^0.8" serde = { version = "^1.0", default-features = false, features = ["derive"] } thiserror = "^1.0" diff --git a/contracts/cw2981-royalties/.cargo/config b/contracts/cw2981-royalties/.cargo/config.toml similarity index 100% rename from contracts/cw2981-royalties/.cargo/config rename to contracts/cw2981-royalties/.cargo/config.toml diff --git a/contracts/cw2981-royalties/Cargo.toml b/contracts/cw2981-royalties/Cargo.toml index 663bdf6c6..830100802 100644 --- a/contracts/cw2981-royalties/Cargo.toml +++ b/contracts/cw2981-royalties/Cargo.toml @@ -14,8 +14,6 @@ rust-version = { workspace = true } crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/cw2981-royalties/src/lib.rs b/contracts/cw2981-royalties/src/lib.rs index 091241330..443539394 100644 --- a/contracts/cw2981-royalties/src/lib.rs +++ b/contracts/cw2981-royalties/src/lib.rs @@ -132,7 +132,7 @@ mod tests { use cosmwasm_std::{from_json, Uint128}; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; use cw721::msg::Cw721InstantiateMsg; use cw721::traits::Cw721Query; use state::Cw2981Contract; @@ -143,8 +143,8 @@ mod tests { fn use_metadata_extension() { let mut deps = mock_dependencies(); let contract = Cw2981Contract::default(); - - let info = mock_info(CREATOR, &[]); + let creator = deps.api.addr_make(CREATOR); + let info = message_info(&creator, &[]); let init_msg = Cw721InstantiateMsg { name: "SpaceShips".to_string(), symbol: "SPACE".to_string(), @@ -164,7 +164,7 @@ mod tests { }); let exec_msg = ExecuteMsg::Mint { token_id: token_id.to_string(), - owner: "john".to_string(), + owner: deps.api.addr_make("john").to_string(), token_uri: token_uri.clone(), extension: extension.clone(), }; @@ -182,8 +182,8 @@ mod tests { fn validate_royalty_information() { let mut deps = mock_dependencies(); let _contract = Cw2981Contract::default(); - - let info = mock_info(CREATOR, &[]); + let creator = deps.api.addr_make(CREATOR); + let info = message_info(&creator, &[]); let init_msg = Cw721InstantiateMsg { name: "SpaceShips".to_string(), symbol: "SPACE".to_string(), @@ -215,8 +215,8 @@ mod tests { fn check_royalties_response() { let mut deps = mock_dependencies(); let _contract = Cw2981Contract::default(); - - let info = mock_info(CREATOR, &[]); + let creator = deps.api.addr_make(CREATOR); + let info = message_info(&creator, &[]); let init_msg = Cw721InstantiateMsg { name: "SpaceShips".to_string(), symbol: "SPACE".to_string(), @@ -230,7 +230,7 @@ mod tests { let token_id = "Enterprise"; let exec_msg = ExecuteMsg::Mint { token_id: token_id.to_string(), - owner: "john".to_string(), + owner: deps.api.addr_make("john").to_string(), token_uri: Some("https://starships.example.com/Starship/Enterprise.json".into()), extension: Some(MetadataWithRoyalty { description: Some("Spaceship with Warp Drive".into()), @@ -256,8 +256,8 @@ mod tests { #[test] fn check_token_royalties() { let mut deps = mock_dependencies(); - - let info = mock_info(CREATOR, &[]); + let creator = deps.api.addr_make(CREATOR); + let info = message_info(&creator, &[]); let init_msg = Cw721InstantiateMsg { name: "SpaceShips".to_string(), symbol: "SPACE".to_string(), @@ -270,15 +270,15 @@ mod tests { entry::instantiate(deps.as_mut(), env.clone(), info.clone(), init_msg).unwrap(); let token_id = "Enterprise"; - let owner = "jeanluc"; + let owner = deps.api.addr_make("jeanluc"); let exec_msg = ExecuteMsg::Mint { token_id: token_id.to_string(), - owner: owner.into(), + owner: owner.to_string(), token_uri: Some("https://starships.example.com/Starship/Enterprise.json".into()), extension: Some(MetadataWithRoyalty { description: Some("Spaceship with Warp Drive".into()), name: Some("Starship USS Enterprise".to_string()), - royalty_payment_address: Some("jeanluc".to_string()), + royalty_payment_address: Some(owner.to_string()), royalty_percentage: Some(10), ..MetadataWithRoyalty::default() }), @@ -286,7 +286,7 @@ mod tests { entry::execute(deps.as_mut(), mock_env(), info.clone(), exec_msg).unwrap(); let expected = RoyaltiesInfoResponse { - address: owner.into(), + address: owner.to_string(), royalty_amount: Uint128::new(10), }; let res = @@ -305,15 +305,15 @@ mod tests { // check for rounding down // which is the default behaviour let voyager_token_id = "Voyager"; - let owner = "janeway"; + let owner = deps.api.addr_make("janeway"); let voyager_exec_msg = ExecuteMsg::Mint { token_id: voyager_token_id.to_string(), - owner: owner.into(), + owner: owner.to_string(), token_uri: Some("https://starships.example.com/Starship/Voyager.json".into()), extension: Some(MetadataWithRoyalty { description: Some("Spaceship with Warp Drive".into()), name: Some("Starship USS Voyager".to_string()), - royalty_payment_address: Some("janeway".to_string()), + royalty_payment_address: Some(owner.to_string()), royalty_percentage: Some(4), ..MetadataWithRoyalty::default() }), @@ -323,7 +323,7 @@ mod tests { // 43 x 0.04 (i.e., 4%) should be 1.72 // we expect this to be rounded down to 1 let voyager_expected = RoyaltiesInfoResponse { - address: owner.into(), + address: owner.to_string(), royalty_amount: Uint128::new(1), }; diff --git a/contracts/cw2981-royalties/src/query.rs b/contracts/cw2981-royalties/src/query.rs index ffc50da18..3a527a9d4 100644 --- a/contracts/cw2981-royalties/src/query.rs +++ b/contracts/cw2981-royalties/src/query.rs @@ -30,7 +30,7 @@ pub fn query_royalties_info( }, None => Decimal::percent(0), }; - let royalty_from_sale_price = sale_price * royalty_percentage; + let royalty_from_sale_price = sale_price.mul_floor(royalty_percentage); let royalty_address = match token_info.extension { Some(ext) => ext.royalty_payment_address.unwrap_or_default(), diff --git a/contracts/cw721-base/.cargo/config b/contracts/cw721-base/.cargo/config.toml similarity index 100% rename from contracts/cw721-base/.cargo/config rename to contracts/cw721-base/.cargo/config.toml diff --git a/contracts/cw721-base/Cargo.toml b/contracts/cw721-base/Cargo.toml index 55bc90761..23c88f1db 100644 --- a/contracts/cw721-base/Cargo.toml +++ b/contracts/cw721-base/Cargo.toml @@ -19,8 +19,6 @@ doctest = false # disable doc tests crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/cw721-base/src/lib.rs b/contracts/cw721-base/src/lib.rs index 0b6f2601f..c5f68eb6d 100644 --- a/contracts/cw721-base/src/lib.rs +++ b/contracts/cw721-base/src/lib.rs @@ -90,7 +90,7 @@ pub mod entry { mod tests { use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; use cw721::traits::{Cw721Execute, Cw721Query}; use extension::Cw721BaseExtensions; use msg::{ExecuteMsg, InstantiateMsg}; @@ -102,7 +102,8 @@ mod tests { fn use_empty_metadata_extension() { let mut deps = mock_dependencies(); let contract = Cw721BaseExtensions::default(); - let info = mock_info(CREATOR, &[]); + let creator = deps.api.addr_make(CREATOR); + let info = message_info(&creator, &[]); let init_msg = InstantiateMsg { name: "SpaceShips".to_string(), symbol: "SPACE".to_string(), @@ -118,9 +119,10 @@ mod tests { let token_id = "Enterprise"; let token_uri = Some("https://starships.example.com/Starship/Enterprise.json".into()); let extension = Some(Empty {}); + let owner = deps.api.addr_make("john"); let exec_msg = ExecuteMsg::Mint { token_id: token_id.to_string(), - owner: "john".to_string(), + owner: owner.to_string(), token_uri: token_uri.clone(), extension: extension.clone(), }; diff --git a/contracts/cw721-expiration/.cargo/config b/contracts/cw721-expiration/.cargo/config.toml similarity index 100% rename from contracts/cw721-expiration/.cargo/config rename to contracts/cw721-expiration/.cargo/config.toml diff --git a/contracts/cw721-expiration/Cargo.toml b/contracts/cw721-expiration/Cargo.toml index f869ca62d..b0db71c39 100644 --- a/contracts/cw721-expiration/Cargo.toml +++ b/contracts/cw721-expiration/Cargo.toml @@ -14,8 +14,6 @@ rust-version = { workspace = true } crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/cw721-expiration/src/contract_tests.rs b/contracts/cw721-expiration/src/contract_tests.rs index ea085da06..e292324cb 100644 --- a/contracts/cw721-expiration/src/contract_tests.rs +++ b/contracts/cw721-expiration/src/contract_tests.rs @@ -1,7 +1,7 @@ -use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env, MockApi}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, CosmosMsg, DepsMut, Response, StdError, WasmMsg, + from_json, to_json_binary, Addr, CosmosMsg, DepsMut, MessageInfo, Response, StdError, WasmMsg, }; use cw721::error::Cw721ContractError; @@ -19,15 +19,39 @@ use crate::state::DefaultCw721ExpirationContract; use crate::{ error::ContractError, msg::InstantiateMsg, msg::QueryMsg, DefaultOptionalNftExtension, }; +pub struct MockAddrFactory<'a> { + api: MockApi, + addrs: std::collections::BTreeMap<&'a str, Addr>, +} + +impl<'a> MockAddrFactory<'a> { + pub fn new(api: MockApi) -> Self { + Self { + api, + addrs: std::collections::BTreeMap::new(), + } + } + + pub fn addr(&mut self, name: &'a str) -> Addr { + self.addrs + .entry(name) + .or_insert(self.api.addr_make(name)) + .clone() + } + + pub fn info(&mut self, name: &'a str) -> MessageInfo { + message_info(&self.addr(name), &[]) + } +} -const MINTER_ADDR: &str = "minter"; -const CREATOR_ADDR: &str = "creator"; const CONTRACT_NAME: &str = "Magic Power"; const SYMBOL: &str = "MGK"; fn setup_contract( deps: DepsMut<'_>, expiration_days: u16, + creator: &Addr, + minter: &Addr, ) -> DefaultCw721ExpirationContract<'static> { let contract = DefaultCw721ExpirationContract::default(); let msg = InstantiateMsg { @@ -35,11 +59,11 @@ fn setup_contract( name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: None, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), withdraw_address: None, }; - let info = mock_info("creator", &[]); + let info = message_info(creator, &[]); let res = contract.instantiate(deps, mock_env(), info, msg).unwrap(); assert_eq!(0, res.messages.len()); contract @@ -49,17 +73,19 @@ fn setup_contract( fn proper_instantiation() { let mut deps = mock_dependencies(); let contract = DefaultCw721ExpirationContract::default(); - + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); let msg = InstantiateMsg { expiration_days: 1, name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: None, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), - withdraw_address: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), + withdraw_address: Some(creator.to_string()), }; - let info = mock_info("creator", &[]); + let info = addrs.info("creator"); let env = mock_env(); // we can just call .unwrap() to assert this was a success @@ -70,9 +96,9 @@ fn proper_instantiation() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(MINTER_ADDR)), minter_ownership.owner); + assert_eq!(Some(minter), minter_ownership.owner); let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(CREATOR_ADDR)), creator_ownership.owner); + assert_eq!(Some(creator.clone()), creator_ownership.owner); let collection_info = contract .base_contract .query_collection_info_and_extension(deps.as_ref()) @@ -93,7 +119,7 @@ fn proper_instantiation() { .withdraw_address .may_load(deps.as_ref().storage) .unwrap(); - assert_eq!(Some(CREATOR_ADDR.to_string()), withdraw_address); + assert_eq!(Some(creator.to_string()), withdraw_address); let count = contract .base_contract @@ -112,17 +138,19 @@ fn proper_instantiation() { fn proper_instantiation_with_collection_info() { let mut deps = mock_dependencies(); let contract = DefaultCw721ExpirationContract::default(); - + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); let msg = InstantiateMsg { expiration_days: 1, name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: None, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), - withdraw_address: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), + withdraw_address: Some(creator.to_string()), }; - let info = mock_info("creator", &[]); + let info = addrs.info("creator"); let env = mock_env(); // we can just call .unwrap() to assert this was a success @@ -133,9 +161,9 @@ fn proper_instantiation_with_collection_info() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(MINTER_ADDR)), minter_ownership.owner); + assert_eq!(Some(minter), minter_ownership.owner); let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(CREATOR_ADDR)), creator_ownership.owner); + assert_eq!(Some(creator.clone()), creator_ownership.owner); let collection_info = contract .base_contract .query_collection_info_and_extension(deps.as_ref()) @@ -156,7 +184,7 @@ fn proper_instantiation_with_collection_info() { .withdraw_address .may_load(deps.as_ref().storage) .unwrap(); - assert_eq!(Some(CREATOR_ADDR.to_string()), withdraw_address); + assert_eq!(Some(creator.to_string()), withdraw_address); let count = contract .base_contract @@ -174,20 +202,23 @@ fn proper_instantiation_with_collection_info() { #[test] fn test_mint() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); let token_id = "atomize".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/atomize".to_string(); - + let owner = addrs.addr("medusa"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("medusa"), + owner: owner.to_string(), token_uri: Some(token_uri.clone()), extension: None, }; // random cannot mint - let random = mock_info("random", &[]); + let random = addrs.info("random"); let env = mock_env(); let err = contract .execute(deps.as_mut(), env.clone(), random, mint_msg.clone()) @@ -195,7 +226,7 @@ fn test_mint() { assert_eq!(err, ContractError::Cw721(Cw721ContractError::NotMinter {})); // minter can mint - let allowed = mock_info(MINTER_ADDR, &[]); + let allowed = addrs.info("minter"); let _ = contract .execute(deps.as_mut(), mock_env(), allowed, mint_msg) .unwrap(); @@ -225,7 +256,7 @@ fn test_mint() { ); // owner info is correct - let owner = contract + let owner_res = contract .query_owner_of_include_expired_nft( deps.as_ref(), mock_env(), @@ -235,9 +266,9 @@ fn test_mint() { ) .unwrap(); assert_eq!( - owner, + owner_res, OwnerOfResponse { - owner: String::from("medusa"), + owner: owner.to_string(), approvals: vec![], } ); @@ -252,12 +283,12 @@ fn test_mint() { // Cannot mint same token_id again let mint_msg2 = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("hercules"), + owner: addrs.addr("hercules").to_string(), token_uri: None, extension: None, }; - let allowed = mock_info(MINTER_ADDR, &[]); + let allowed = addrs.info("minter"); let err = contract .execute(deps.as_mut(), mock_env(), allowed, mint_msg2) .unwrap_err(); @@ -274,33 +305,37 @@ fn test_mint() { #[test] fn test_update_minter() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); let token_id = "petrify".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); - + let medusa = addrs.addr("medusa"); let mint_msg = Cw721ExecuteMsg::Mint { token_id, - owner: String::from("medusa"), + owner: medusa.to_string(), token_uri: Some(token_uri.clone()), extension: None, }; // Minter can mint - let minter_info = mock_info(MINTER_ADDR, &[]); + let minter_info = addrs.info("minter"); let _ = contract .execute(deps.as_mut(), mock_env(), minter_info.clone(), mint_msg) .unwrap(); // Update the owner to "random". The new owner should be able to // mint new tokens, the old one should not. + let random = addrs.addr("random"); contract .execute( deps.as_mut(), mock_env(), minter_info.clone(), Cw721ExecuteMsg::UpdateMinterOwnership(Action::TransferOwnership { - new_owner: "random".to_string(), + new_owner: random.to_string(), expiry: None, }), ) @@ -318,14 +353,14 @@ fn test_update_minter() { assert_eq!( ownership, Ownership:: { - owner: Some(Addr::unchecked(MINTER_ADDR)), - pending_owner: Some(Addr::unchecked("random")), + owner: Some(minter), + pending_owner: Some(random.clone()), pending_expiry: None, } ); // Accept the ownership transfer. - let random_info = mock_info("random", &[]); + let random_info = addrs.info("random"); contract .execute( deps.as_mut(), @@ -342,11 +377,11 @@ fn test_update_minter() { .unwrap(), ) .unwrap(); - assert_eq!(minter_ownership.owner, Some(random_info.sender.clone())); + assert_eq!(minter_ownership.owner, Some(random)); let mint_msg = Cw721ExecuteMsg::Mint { token_id: "randoms_token".to_string(), - owner: String::from("medusa"), + owner: addrs.addr("medusa").to_string(), token_uri: Some(token_uri), extension: None, }; @@ -366,14 +401,17 @@ fn test_update_minter() { #[test] fn test_burn() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); let token_id = "petrify".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: MINTER_ADDR.to_string(), + owner: minter.to_string(), token_uri: Some(token_uri), extension: None, }; @@ -384,13 +422,18 @@ fn test_burn() { // mint some NFT let mut env = mock_env(); - let minter = mock_info(MINTER_ADDR, &[]); + let minter_info = addrs.info("minter"); let _ = contract - .execute(deps.as_mut(), env.clone(), minter.clone(), mint_msg.clone()) + .execute( + deps.as_mut(), + env.clone(), + minter_info.clone(), + mint_msg.clone(), + ) .unwrap(); // random not allowed to burn - let random = mock_info("random", &[]); + let random = addrs.info("random"); let err = contract .execute(deps.as_mut(), env.clone(), random, burn_msg.clone()) .unwrap_err(); @@ -401,7 +444,12 @@ fn test_burn() { ); let _ = contract - .execute(deps.as_mut(), env.clone(), minter.clone(), burn_msg.clone()) + .execute( + deps.as_mut(), + env.clone(), + minter_info.clone(), + burn_msg.clone(), + ) .unwrap(); // ensure num tokens decreases @@ -430,14 +478,14 @@ fn test_burn() { // assert invalid nft throws error // - mint again contract - .execute(deps.as_mut(), env.clone(), minter.clone(), mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info.clone(), mint_msg) .unwrap(); // - burn let mint_date = env.block.time; let expiration = env.block.time.plus_days(1); env.block.time = expiration; let error = contract - .execute(deps.as_mut(), env, minter, burn_msg) + .execute(deps.as_mut(), env, minter_info, burn_msg) .unwrap_err(); assert_eq!( error, @@ -452,35 +500,39 @@ fn test_burn() { #[test] fn test_transfer_nft() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); // Mint a token let token_id = "melt".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - let owner = "owner"; + let owner = addrs.addr("owner"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from(owner), + owner: owner.to_string(), token_uri: Some(token_uri), extension: None, }; let mut env = mock_env(); - let minter = mock_info(MINTER_ADDR, &[]); + let minter_info = addrs.info("minter"); contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // random cannot transfer - let random = mock_info("random", &[]); + let random = addrs.addr("random"); + let random_info = addrs.info("random"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("random"), + recipient: random.to_string(), token_id: token_id.clone(), }; let err = contract - .execute(deps.as_mut(), env.clone(), random, transfer_msg) + .execute(deps.as_mut(), env.clone(), random_info, transfer_msg) .unwrap_err(); assert_eq!( err, @@ -488,10 +540,10 @@ fn test_transfer_nft() { ); // owner can - let owner_info = mock_info(owner, &[]); - let new_owner = "random"; + let owner_info = addrs.info("owner"); + let new_owner = addrs.addr("random"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from(new_owner), + recipient: new_owner.to_string(), token_id: token_id.clone(), }; @@ -508,8 +560,8 @@ fn test_transfer_nft() { res, Response::new() .add_attribute("action", "transfer_nft") - .add_attribute("sender", owner) - .add_attribute("recipient", new_owner) + .add_attribute("sender", owner.to_string()) + .add_attribute("recipient", new_owner.to_string()) .add_attribute("token_id", token_id.clone()) ); @@ -533,36 +585,44 @@ fn test_transfer_nft() { #[test] fn test_send_nft() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); // Mint a token let token_id = "melt".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - + let venus = addrs.addr("venus"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("venus"), + owner: venus.to_string(), token_uri: Some(token_uri), extension: None, }; let mut env = mock_env(); - let minter = mock_info(MINTER_ADDR, &[]); + let minter = addrs.info("minter"); contract .execute(deps.as_mut(), env.clone(), minter, mint_msg) .unwrap(); let msg = to_json_binary("You now have the melting power").unwrap(); - let target = String::from("another_contract"); + let target = addrs.addr("another_contract"); let send_msg = Cw721ExecuteMsg::SendNft { - contract: target.clone(), + contract: target.to_string(), token_id: token_id.clone(), msg: msg.clone(), }; - let random = mock_info("random", &[]); + let random_info = addrs.info("random"); let err = contract - .execute(deps.as_mut(), env.clone(), random, send_msg.clone()) + .execute( + deps.as_mut(), + env.clone(), + random_info.clone(), + send_msg.clone(), + ) .unwrap_err(); assert_eq!( err, @@ -570,13 +630,17 @@ fn test_send_nft() { ); // but owner can - let random = mock_info("venus", &[]); + let venus_info: MessageInfo = addrs.info("venus"); let res = contract - .execute(deps.as_mut(), env.clone(), random.clone(), send_msg.clone()) + .execute( + deps.as_mut(), + env.clone(), + venus_info.clone(), + send_msg.clone(), + ) .unwrap(); - let payload = Cw721ReceiveMsg { - sender: String::from("venus"), + sender: venus.to_string(), token_id: token_id.clone(), msg, }; @@ -584,7 +648,7 @@ fn test_send_nft() { // ensure expected serializes as we think it should match &expected { CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, .. }) => { - assert_eq!(contract_addr, &target) + assert_eq!(contract_addr, &target.to_string()) } m => panic!("Unexpected message type: {m:?}"), } @@ -594,8 +658,8 @@ fn test_send_nft() { Response::new() .add_message(expected) .add_attribute("action", "send_nft") - .add_attribute("sender", "venus") - .add_attribute("recipient", "another_contract") + .add_attribute("sender", venus.to_string()) + .add_attribute("recipient", target.to_string()) .add_attribute("token_id", token_id.clone()) ); @@ -604,7 +668,7 @@ fn test_send_nft() { let expiration = env.block.time.plus_days(1); env.block.time = expiration; let error = contract - .execute(deps.as_mut(), env, random, send_msg) + .execute(deps.as_mut(), env, random_info, send_msg) .unwrap_err(); assert_eq!( error, @@ -619,21 +683,24 @@ fn test_send_nft() { #[test] fn test_approve_revoke() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); // Mint a token let token_id = "grow".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/grow".to_string(); - + let demeter = addrs.addr("demeter"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("demeter"), + owner: demeter.to_string(), token_uri: Some(token_uri), extension: None, }; let mut env = mock_env(); - let minter = mock_info(MINTER_ADDR, &[]); + let minter = addrs.info("minter"); contract .execute(deps.as_mut(), env.clone(), minter, mint_msg) .unwrap(); @@ -644,7 +711,7 @@ fn test_approve_revoke() { deps.as_ref(), env.clone(), token_id.clone(), - String::from("demeter"), + demeter.to_string(), false, false, ) @@ -653,28 +720,29 @@ fn test_approve_revoke() { res, ApprovalResponse { approval: Approval { - spender: Addr::unchecked("demeter"), + spender: demeter.clone(), expires: Expiration::Never {} } } ); // Give random transferring power + let random = addrs.addr("random"); let approve_msg = Cw721ExecuteMsg::Approve { - spender: String::from("random"), + spender: random.to_string(), token_id: token_id.clone(), expires: None, }; - let owner = mock_info("demeter", &[]); + let owner_info = addrs.info("demeter"); let res = contract - .execute(deps.as_mut(), env.clone(), owner, approve_msg) + .execute(deps.as_mut(), env.clone(), owner_info, approve_msg) .unwrap(); assert_eq!( res, Response::new() .add_attribute("action", "approve") - .add_attribute("sender", "demeter") - .add_attribute("spender", "random") + .add_attribute("sender", demeter.to_string()) + .add_attribute("spender", random.to_string()) .add_attribute("token_id", token_id.clone()) ); @@ -684,7 +752,7 @@ fn test_approve_revoke() { deps.as_ref(), env.clone(), token_id.clone(), - String::from("random"), + random.to_string(), true, false, ) @@ -693,20 +761,21 @@ fn test_approve_revoke() { res, ApprovalResponse { approval: Approval { - spender: Addr::unchecked("random"), + spender: random.clone(), expires: Expiration::Never {} } } ); // random can now transfer - let random = mock_info("random", &[]); + let random_info = addrs.info("random"); + let person = addrs.addr("person"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("person"), + recipient: person.to_string(), token_id: token_id.clone(), }; contract - .execute(deps.as_mut(), env.clone(), random, transfer_msg) + .execute(deps.as_mut(), env.clone(), random_info, transfer_msg) .unwrap(); // Approvals are removed / cleared @@ -724,36 +793,36 @@ fn test_approve_revoke() { assert_eq!( res, OwnerOfResponse { - owner: String::from("person"), + owner: person.to_string(), approvals: vec![], } ); // Approve, revoke, and check for empty, to test revoke let approve_msg = Cw721ExecuteMsg::Approve { - spender: String::from("random"), + spender: random.to_string(), token_id: token_id.clone(), expires: None, }; - let owner = mock_info("person", &[]); + let owner_info = addrs.info("person"); contract .execute( deps.as_mut(), env.clone(), - owner.clone(), + owner_info.clone(), approve_msg.clone(), ) .unwrap(); let revoke_msg = Cw721ExecuteMsg::Revoke { - spender: String::from("random"), + spender: random.to_string(), token_id: token_id.clone(), }; contract .execute( deps.as_mut(), env.clone(), - owner.clone(), + owner_info.clone(), revoke_msg.clone(), ) .unwrap(); @@ -768,7 +837,7 @@ fn test_approve_revoke() { assert_eq!( res, OwnerOfResponse { - owner: String::from("person"), + owner: person.to_string(), approvals: vec![], } ); @@ -778,7 +847,7 @@ fn test_approve_revoke() { let expiration = env.block.time.plus_days(1); env.block.time = expiration; let error = contract - .execute(deps.as_mut(), env.clone(), owner.clone(), approve_msg) + .execute(deps.as_mut(), env.clone(), owner_info.clone(), approve_msg) .unwrap_err(); assert_eq!( error, @@ -791,7 +860,7 @@ fn test_approve_revoke() { // assert revoke of invalid nft throws error let error = contract - .execute(deps.as_mut(), env, owner, revoke_msg) + .execute(deps.as_mut(), env, owner_info, revoke_msg) .unwrap_err(); assert_eq!( error, @@ -806,7 +875,10 @@ fn test_approve_revoke() { #[test] fn test_approve_all_revoke_all() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); // Mint a couple tokens (from the same owner) let token_id1 = "grow1".to_string(); @@ -814,22 +886,22 @@ fn test_approve_all_revoke_all() { let token_id2 = "grow2".to_string(); let token_uri2 = "https://www.merriam-webster.com/dictionary/grow2".to_string(); - + let demeter = addrs.addr("demeter"); let mint_msg1 = Cw721ExecuteMsg::Mint { token_id: token_id1.clone(), - owner: String::from("demeter"), + owner: demeter.to_string(), token_uri: Some(token_uri1), extension: None, }; - let minter = mock_info(MINTER_ADDR, &[]); + let minter = addrs.info("minter"); contract .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg1) .unwrap(); let mint_msg2 = Cw721ExecuteMsg::Mint { token_id: token_id2.clone(), - owner: String::from("demeter"), + owner: demeter.to_string(), token_uri: Some(token_uri2), extension: None, }; @@ -857,11 +929,12 @@ fn test_approve_all_revoke_all() { assert_eq!(vec![token_id2.clone()], tokens.tokens); // demeter gives random full (operator) power over her tokens + let random = addrs.addr("random"); let approve_all_msg = Cw721ExecuteMsg::ApproveAll { - operator: String::from("random"), + operator: random.to_string(), expires: None, }; - let owner = mock_info("demeter", &[]); + let owner = addrs.info("demeter"); let res = contract .execute(deps.as_mut(), mock_env(), owner, approve_all_msg) .unwrap(); @@ -869,44 +942,46 @@ fn test_approve_all_revoke_all() { res, Response::new() .add_attribute("action", "approve_all") - .add_attribute("sender", "demeter") - .add_attribute("operator", "random") + .add_attribute("sender", demeter.to_string()) + .add_attribute("operator", random.to_string()) ); // random can now transfer - let random = mock_info("random", &[]); + let random_info = addrs.info("random"); + let person = addrs.addr("person"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("person"), + recipient: person.to_string(), token_id: token_id1, }; contract - .execute(deps.as_mut(), mock_env(), random.clone(), transfer_msg) + .execute(deps.as_mut(), mock_env(), random_info.clone(), transfer_msg) .unwrap(); - + let other_contract = addrs.addr("other_contract"); // random can now send let inner_msg = WasmMsg::Execute { - contract_addr: "another_contract".into(), + contract_addr: other_contract.to_string(), msg: to_json_binary("You now also have the growing power").unwrap(), funds: vec![], }; let msg: CosmosMsg = CosmosMsg::Wasm(inner_msg); let send_msg = Cw721ExecuteMsg::SendNft { - contract: String::from("another_contract"), + contract: other_contract.to_string(), token_id: token_id2, msg: to_json_binary(&msg).unwrap(), }; contract - .execute(deps.as_mut(), mock_env(), random, send_msg) + .execute(deps.as_mut(), mock_env(), random_info, send_msg) .unwrap(); // Approve_all, revoke_all, and check for empty, to test revoke_all + let operator = addrs.addr("operator"); let approve_all_msg = Cw721ExecuteMsg::ApproveAll { - operator: String::from("operator"), + operator: operator.to_string(), expires: None, }; // person is now the owner of the tokens - let owner = mock_info("person", &[]); + let owner = addrs.info("person"); contract .execute(deps.as_mut(), mock_env(), owner, approve_all_msg) .unwrap(); @@ -917,8 +992,8 @@ fn test_approve_all_revoke_all() { .query_operator( deps.as_ref(), &mock_env(), - String::from("person"), - String::from("operator"), + person.to_string(), + operator.to_string(), true, ) .unwrap(); @@ -926,22 +1001,23 @@ fn test_approve_all_revoke_all() { res, OperatorResponse { approval: Approval { - spender: Addr::unchecked("operator"), + spender: operator.clone(), expires: Expiration::Never {} } } ); // query for other should throw error + let other = addrs.addr("other"); let res = contract.base_contract.query_operator( deps.as_ref(), &mock_env(), - String::from("person"), - String::from("other"), + person.to_string(), + other.to_string(), true, ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } @@ -950,7 +1026,7 @@ fn test_approve_all_revoke_all() { .query_operators( deps.as_ref(), &mock_env(), - String::from("person"), + person.to_string(), true, None, None, @@ -960,7 +1036,7 @@ fn test_approve_all_revoke_all() { res, OperatorsResponse { operators: vec![cw721::Approval { - spender: Addr::unchecked("operator"), + spender: operator.clone(), expires: Expiration::Never {} }] } @@ -968,13 +1044,19 @@ fn test_approve_all_revoke_all() { // second approval let buddy_expires = Expiration::AtHeight(1234567); + let buddy = addrs.addr("buddy"); let approve_all_msg = Cw721ExecuteMsg::ApproveAll { - operator: String::from("buddy"), + operator: buddy.to_string(), expires: Some(buddy_expires), }; - let owner = mock_info("person", &[]); + let owner_info = addrs.info("person"); contract - .execute(deps.as_mut(), mock_env(), owner.clone(), approve_all_msg) + .execute( + deps.as_mut(), + mock_env(), + owner_info.clone(), + approve_all_msg, + ) .unwrap(); // and paginate queries @@ -983,9 +1065,9 @@ fn test_approve_all_revoke_all() { .query_operators( deps.as_ref(), &mock_env(), - String::from("person"), + person.to_string(), true, - None, + Some(operator.to_string()), Some(1), ) .unwrap(); @@ -993,7 +1075,7 @@ fn test_approve_all_revoke_all() { res, OperatorsResponse { operators: vec![cw721::Approval { - spender: Addr::unchecked("buddy"), + spender: buddy.clone(), expires: buddy_expires, }] } @@ -1003,39 +1085,45 @@ fn test_approve_all_revoke_all() { .query_operators( deps.as_ref(), &mock_env(), - String::from("person"), + person.to_string(), true, - Some(String::from("buddy")), + None, Some(2), ) .unwrap(); assert_eq!( res, OperatorsResponse { - operators: vec![cw721::Approval { - spender: Addr::unchecked("operator"), - expires: Expiration::Never {} - }] + operators: vec![ + cw721::Approval { + spender: operator.clone(), + expires: Expiration::Never {} + }, + cw721::Approval { + spender: buddy.clone(), + expires: buddy_expires, + } + ] } ); let revoke_all_msg = Cw721ExecuteMsg::RevokeAll { - operator: String::from("operator"), + operator: operator.to_string(), }; contract - .execute(deps.as_mut(), mock_env(), owner, revoke_all_msg) + .execute(deps.as_mut(), mock_env(), owner_info, revoke_all_msg) .unwrap(); // query for operator should return error let res = contract.base_contract.query_operator( deps.as_ref(), &mock_env(), - String::from("person"), - String::from("operator"), + person.to_string(), + operator.to_string(), true, ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } @@ -1045,7 +1133,7 @@ fn test_approve_all_revoke_all() { .query_operators( deps.as_ref(), &mock_env(), - String::from("person"), + person.to_string(), false, None, None, @@ -1055,7 +1143,7 @@ fn test_approve_all_revoke_all() { res, OperatorsResponse { operators: vec![cw721::Approval { - spender: Addr::unchecked("buddy"), + spender: buddy.clone(), expires: buddy_expires, }] } @@ -1069,7 +1157,7 @@ fn test_approve_all_revoke_all() { .query_operators( deps.as_ref(), &late_env, - String::from("person"), + person.to_string(), false, None, None, @@ -1081,13 +1169,13 @@ fn test_approve_all_revoke_all() { let res = contract.base_contract.query_operator( deps.as_ref(), &late_env, - String::from("person"), - String::from("buddy"), + person.to_string(), + buddy.to_string(), false, ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } } @@ -1095,44 +1183,47 @@ fn test_approve_all_revoke_all() { #[test] fn test_tokens_by_owner() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); // Mint a couple tokens (from the same owner) let token_id1 = "grow1".to_string(); - let demeter = String::from("demeter"); + let demeter = addrs.addr("demeter"); let token_id2 = "grow2".to_string(); - let ceres = String::from("ceres"); + let ceres = addrs.addr("ceres"); let token_id3 = "sing".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id1.clone(), - owner: demeter.clone(), + owner: demeter.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg) + .execute(deps.as_mut(), mock_env(), minter_info.clone(), mint_msg) .unwrap(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id2.clone(), - owner: ceres.clone(), + owner: ceres.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg) + .execute(deps.as_mut(), mock_env(), minter_info.clone(), mint_msg) .unwrap(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id3.clone(), - owner: demeter.clone(), + owner: demeter.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg) + .execute(deps.as_mut(), mock_env(), minter_info, mint_msg) .unwrap(); // get all tokens in order: @@ -1165,7 +1256,7 @@ fn test_tokens_by_owner() { .query_tokens_include_expired_nft( deps.as_ref(), mock_env(), - demeter.clone(), + demeter.to_string(), None, None, false, @@ -1173,7 +1264,14 @@ fn test_tokens_by_owner() { .unwrap(); assert_eq!(&by_demeter, &tokens.tokens); let tokens = contract - .query_tokens_include_expired_nft(deps.as_ref(), mock_env(), ceres, None, None, false) + .query_tokens_include_expired_nft( + deps.as_ref(), + mock_env(), + ceres.to_string(), + None, + None, + false, + ) .unwrap(); assert_eq!(&by_ceres, &tokens.tokens); @@ -1182,7 +1280,7 @@ fn test_tokens_by_owner() { .query_tokens_include_expired_nft( deps.as_ref(), mock_env(), - demeter.clone(), + demeter.to_string(), None, Some(1), false, @@ -1193,7 +1291,7 @@ fn test_tokens_by_owner() { .query_tokens_include_expired_nft( deps.as_ref(), mock_env(), - demeter, + demeter.to_string(), Some(by_demeter[0].clone()), Some(3), false, @@ -1205,16 +1303,19 @@ fn test_tokens_by_owner() { #[test] fn test_nft_info() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner, + owner: owner.to_string(), token_uri: None, extension: None, }; @@ -1247,21 +1348,24 @@ fn test_nft_info() { #[test] fn test_all_nft_info() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner, + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1295,21 +1399,24 @@ fn test_all_nft_info() { #[test] fn test_owner_of() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner, + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1343,21 +1450,24 @@ fn test_owner_of() { #[test] fn test_approval() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: owner.clone(), + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1366,7 +1476,7 @@ fn test_approval() { deps.as_ref(), env.clone(), token_id.clone(), - owner.clone(), + owner.to_string(), false, false, ) @@ -1381,7 +1491,7 @@ fn test_approval() { deps.as_ref(), env, token_id.clone(), - owner, + owner.to_string(), false, false, ) @@ -1399,21 +1509,24 @@ fn test_approval() { #[test] fn test_approvals() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner, + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1447,21 +1560,24 @@ fn test_approvals() { #[test] fn test_tokens() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: owner.clone(), + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1469,7 +1585,7 @@ fn test_tokens() { .query_tokens_include_expired_nft( deps.as_ref(), env.clone(), - owner.clone(), + owner.to_string(), None, None, false, @@ -1483,7 +1599,7 @@ fn test_tokens() { .query_tokens_include_expired_nft( deps.as_ref(), env.clone(), - owner.clone(), + owner.to_string(), None, None, false, @@ -1493,7 +1609,7 @@ fn test_tokens() { // assert invalid nft is returned let tokens = contract - .query_tokens_include_expired_nft(deps.as_ref(), env, owner, None, None, true) + .query_tokens_include_expired_nft(deps.as_ref(), env, owner.to_string(), None, None, true) .unwrap(); assert_eq!( tokens, @@ -1506,21 +1622,24 @@ fn test_tokens() { #[test] fn test_all_tokens() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut(), 1); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), 1, &creator, &minter); + let minter_info = addrs.info("minter"); let token_id = "grow1".to_string(); - let owner = String::from("ark"); + let owner = addrs.addr("ark"); let mut env = mock_env(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: owner.clone(), + owner: owner.to_string(), token_uri: None, extension: None, }; contract - .execute(deps.as_mut(), env.clone(), minter, mint_msg) + .execute(deps.as_mut(), env.clone(), minter_info, mint_msg) .unwrap(); // assert valid nft is returned @@ -1532,7 +1651,14 @@ fn test_all_tokens() { let expiration = env.block.time.plus_days(1); env.block.time = expiration; let tokens = contract - .query_tokens_include_expired_nft(deps.as_ref(), env.clone(), owner, None, None, false) + .query_tokens_include_expired_nft( + deps.as_ref(), + env.clone(), + owner.to_string(), + None, + None, + false, + ) .unwrap(); assert_eq!(tokens, TokensResponse { tokens: vec![] }); diff --git a/contracts/cw721-expiration/src/lib.rs b/contracts/cw721-expiration/src/lib.rs index 98848c370..0c32c5cea 100644 --- a/contracts/cw721-expiration/src/lib.rs +++ b/contracts/cw721-expiration/src/lib.rs @@ -77,7 +77,7 @@ pub mod entry { #[cfg(test)] mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; use cw2::ContractVersion; use crate::{error::ContractError, msg::InstantiateMsg, state::Cw721ExpirationContract}; @@ -87,19 +87,21 @@ mod tests { #[test] fn proper_cw2_initialization() { let mut deps = mock_dependencies(); - + let info = message_info(&deps.api.addr_make("mrt"), &[]); + let creator = deps.api.addr_make("creator"); + let minter = deps.api.addr_make("minter"); // assert min expiration let error = entry::instantiate( deps.as_mut(), mock_env(), - mock_info("mrt", &[]), + info.clone(), InstantiateMsg { expiration_days: 0, name: "collection_name".into(), symbol: "collection_symbol".into(), collection_info_extension: None, - minter: Some("minter".into()), - creator: Some("creator".into()), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), withdraw_address: None, }, ) @@ -110,14 +112,14 @@ mod tests { entry::instantiate( deps.as_mut(), mock_env(), - mock_info("mrt", &[]), + info, InstantiateMsg { expiration_days: 1, name: "name".into(), symbol: "symbol".into(), collection_info_extension: None, - minter: Some("minter".into()), - creator: Some("creator".into()), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), withdraw_address: None, }, ) diff --git a/contracts/cw721-expiration/src/state.rs b/contracts/cw721-expiration/src/state.rs index 6bcb57d70..5b6cb7130 100644 --- a/contracts/cw721-expiration/src/state.rs +++ b/contracts/cw721-expiration/src/state.rs @@ -12,8 +12,8 @@ use cw_storage_plus::{Item, Map}; /// - `Empty` for custom query msg for custom contract logic. /// - `Empty` for custom response msg for custom contract logic. pub struct DefaultCw721ExpirationContract<'a> { - pub expiration_days: Item<'a, u16>, // max 65535 days - pub mint_timestamps: Map<'a, &'a str, Timestamp>, + pub expiration_days: Item, // max 65535 days + pub mint_timestamps: Map<&'a str, Timestamp>, pub base_contract: Cw721OnchainExtensions<'a>, } @@ -28,8 +28,8 @@ impl Default for DefaultCw721ExpirationContract<'static> { } pub struct Cw721ExpirationContract<'a> { - pub expiration_days: Item<'a, u16>, // max 65535 days - pub mint_timestamps: Map<'a, &'a str, Timestamp>, + pub expiration_days: Item, // max 65535 days + pub mint_timestamps: Map<&'a str, Timestamp>, pub base_contract: Cw721OnchainExtensions<'a>, } diff --git a/contracts/cw721-fixed-price/.cargo/config b/contracts/cw721-fixed-price/.cargo/config.toml similarity index 100% rename from contracts/cw721-fixed-price/.cargo/config rename to contracts/cw721-fixed-price/.cargo/config.toml diff --git a/contracts/cw721-fixed-price/Cargo.toml b/contracts/cw721-fixed-price/Cargo.toml index 8830f18ca..3d4b1a385 100644 --- a/contracts/cw721-fixed-price/Cargo.toml +++ b/contracts/cw721-fixed-price/Cargo.toml @@ -13,8 +13,6 @@ rust-version = { workspace = true } crate-type = ["cdylib", "rlib"] [features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/cw721-fixed-price/src/contract.rs b/contracts/cw721-fixed-price/src/contract.rs index c48da554f..b76866410 100644 --- a/contracts/cw721-fixed-price/src/contract.rs +++ b/contracts/cw721-fixed-price/src/contract.rs @@ -16,7 +16,7 @@ use cw721::{ DefaultOptionalCollectionExtension, DefaultOptionalCollectionExtensionMsg, DefaultOptionalNftExtensionMsg, }; -use cw_utils::parse_reply_instantiate_data; +use cw_utils::parse_instantiate_response_data; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw721-fixed-price"; @@ -75,6 +75,7 @@ pub fn instantiate( id: INSTANTIATE_TOKEN_REPLY_ID, gas_limit: None, reply_on: ReplyOn::Success, + payload: Binary::new(vec![]), }]; Ok(Response::new().add_submessages(sub_msg)) @@ -92,8 +93,9 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result StdResult { let config = Cw721Config::>::default(); - cw_paginate_storage::paginate_map_values( - deps, - &config.collection_extension, - None, - None, - Order::Ascending, - ) + config + .collection_extension + .range(deps.storage, None, None, Order::Ascending) + .map(|kv| Ok(kv?.1)) + .collect() } pub fn query_collection_info_and_extension( @@ -263,7 +261,7 @@ pub fn query_approval( deps: Deps, env: &Env, token_id: String, - spender: String, + spender: Addr, include_expired_approval: bool, ) -> StdResult { let token = Cw721Config::>::default() diff --git a/packages/cw721/src/state.rs b/packages/cw721/src/state.rs index 8a081be4b..43c37a8aa 100644 --- a/packages/cw721/src/state.rs +++ b/packages/cw721/src/state.rs @@ -49,14 +49,14 @@ pub struct Cw721Config< TNftExtension: Cw721State, { /// Note: replaces deprecated/legacy key "nft_info"! - pub collection_info: Item<'a, CollectionInfo>, - pub collection_extension: Map<'a, String, Attribute>, - pub token_count: Item<'a, u64>, + pub collection_info: Item, + pub collection_extension: Map, + pub token_count: Item, /// Stored as (granter, operator) giving operator full control over granter's account. /// NOTE: granter is the owner, so operator has only control for NFTs owned by granter! - pub operators: Map<'a, (&'a Addr, &'a Addr), Expiration>, - pub nft_info: IndexedMap<'a, &'a str, NftInfo, TokenIndexes<'a, TNftExtension>>, - pub withdraw_address: Item<'a, String>, + pub operators: Map<(&'a Addr, &'a Addr), Expiration>, + pub nft_info: IndexedMap<&'a str, NftInfo, TokenIndexes<'a, TNftExtension>>, + pub withdraw_address: Item, } impl Default for Cw721Config<'static, TNftExtension> @@ -82,13 +82,13 @@ where TNftExtension: Cw721State, { fn new( - collection_info_key: &'a str, - collection_info_extension_key: &'a str, - token_count_key: &'a str, - operator_key: &'a str, - nft_info_key: &'a str, - nft_info_owner_key: &'a str, - withdraw_address_key: &'a str, + collection_info_key: &'static str, + collection_info_extension_key: &'static str, + token_count_key: &'static str, + operator_key: &'static str, + nft_info_key: &'static str, + nft_info_owner_key: &'static str, + withdraw_address_key: &'static str, ) -> Self { let indexes = TokenIndexes { owner: MultiIndex::new(token_owner_idx, nft_info_key, nft_info_owner_key), diff --git a/packages/cw721/src/testing/contract_tests.rs b/packages/cw721/src/testing/contract_tests.rs index 8a2de482d..5dacc4edc 100644 --- a/packages/cw721/src/testing/contract_tests.rs +++ b/packages/cw721/src/testing/contract_tests.rs @@ -1,8 +1,8 @@ -use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env, MockApi}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, Coin, CosmosMsg, DepsMut, Empty, Response, StdError, - Timestamp, WasmMsg, + from_json, to_json_binary, Addr, Coin, CosmosMsg, DepsMut, Empty, MessageInfo, Response, + StdError, Timestamp, WasmMsg, }; use crate::error::Cw721ContractError; @@ -22,22 +22,49 @@ use crate::{ use crate::{CollectionExtension, CollectionInfoAndExtensionResponse, RoyaltyInfo}; use cw_ownable::{Action, Ownership, OwnershipError}; -const MINTER_ADDR: &str = "minter"; -const CREATOR_ADDR: &str = "creator"; const CONTRACT_NAME: &str = "Magic Power"; const SYMBOL: &str = "MGK"; -fn setup_contract(deps: DepsMut<'_>) -> Cw721OnchainExtensions<'static> { +pub struct MockAddrFactory<'a> { + api: MockApi, + addrs: std::collections::BTreeMap<&'a str, Addr>, +} + +impl<'a> MockAddrFactory<'a> { + pub fn new(api: MockApi) -> Self { + Self { + api, + addrs: std::collections::BTreeMap::new(), + } + } + + pub fn addr(&mut self, name: &'a str) -> Addr { + self.addrs + .entry(name) + .or_insert(self.api.addr_make(name)) + .clone() + } + + pub fn info(&mut self, name: &'a str) -> MessageInfo { + message_info(&self.addr(name), &[]) + } +} + +fn setup_contract( + deps: DepsMut<'_>, + creator: &Addr, + minter: &Addr, +) -> Cw721OnchainExtensions<'static> { let contract = Cw721OnchainExtensions::default(); let msg = Cw721InstantiateMsg:: { name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: None, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), withdraw_address: None, }; - let info_creator = mock_info(CREATOR_ADDR, &[]); + let info_creator = message_info(creator, &[]); let res = contract .instantiate_with_version( deps, @@ -56,16 +83,18 @@ fn setup_contract(deps: DepsMut<'_>) -> Cw721OnchainExtensions<'static> { fn test_instantiate() { let mut deps = mock_dependencies(); let contract = Cw721OnchainExtensions::default(); - + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); let msg = Cw721InstantiateMsg { name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: None, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), - withdraw_address: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), + withdraw_address: Some(creator.to_string()), }; - let info = mock_info("creator", &[]); + let info = addrs.info("creator"); let env = mock_env(); // we can just call .unwrap() to assert this was a success @@ -83,9 +112,9 @@ fn test_instantiate() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(MINTER_ADDR)), minter_ownership.owner); + assert_eq!(Some(minter), minter_ownership.owner); let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(CREATOR_ADDR)), creator_ownership.owner); + assert_eq!(Some(creator.clone()), creator_ownership.owner); let collection_info = contract .query_collection_info_and_extension(deps.as_ref()) .unwrap(); @@ -104,7 +133,7 @@ fn test_instantiate() { .withdraw_address .may_load(deps.as_ref().storage) .unwrap(); - assert_eq!(Some(CREATOR_ADDR.to_string()), withdraw_address); + assert_eq!(Some(creator.to_string()), withdraw_address); let count = contract.query_num_tokens(deps.as_ref().storage).unwrap(); assert_eq!(0, count.count); @@ -120,7 +149,10 @@ fn test_instantiate() { fn test_instantiate_with_collection_info_and_extension() { let mut deps = mock_dependencies(); let contract = Cw721OnchainExtensions::default(); - + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let payment = addrs.addr("payment"); let collection_info_extension_msg = Some(CollectionExtensionMsg { description: Some("description".to_string()), image: Some("https://moonphases.org".to_string()), @@ -128,7 +160,7 @@ fn test_instantiate_with_collection_info_and_extension() { external_link: Some("https://moonphases.org/".to_string()), start_trading_time: Some(Timestamp::from_seconds(0)), royalty_info: Some(RoyaltyInfoResponse { - payment_address: "payment_address".into(), + payment_address: payment.to_string(), share: "0.1".parse().unwrap(), }), }); @@ -136,11 +168,11 @@ fn test_instantiate_with_collection_info_and_extension() { name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: collection_info_extension_msg, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), - withdraw_address: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), + withdraw_address: Some(creator.to_string()), }; - let info = mock_info("creator", &[]); + let info = addrs.info("creator"); let env = mock_env(); // we can just call .unwrap() to assert this was a success @@ -158,9 +190,9 @@ fn test_instantiate_with_collection_info_and_extension() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(MINTER_ADDR)), minter_ownership.owner); + assert_eq!(Some(minter), minter_ownership.owner); let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(CREATOR_ADDR)), creator_ownership.owner); + assert_eq!(Some(creator.clone()), creator_ownership.owner); let info = contract .query_collection_info_and_extension(deps.as_ref()) .unwrap(); @@ -171,7 +203,7 @@ fn test_instantiate_with_collection_info_and_extension() { external_link: Some("https://moonphases.org/".to_string()), start_trading_time: Some(Timestamp::from_seconds(0)), royalty_info: Some(RoyaltyInfo { - payment_address: Addr::unchecked("payment_address"), + payment_address: payment, share: "0.1".parse().unwrap(), }), }); @@ -190,7 +222,7 @@ fn test_instantiate_with_collection_info_and_extension() { .withdraw_address .may_load(deps.as_ref().storage) .unwrap(); - assert_eq!(Some(CREATOR_ADDR.to_string()), withdraw_address); + assert_eq!(Some(creator.to_string()), withdraw_address); let count = contract.query_num_tokens(deps.as_ref().storage).unwrap(); assert_eq!(0, count.count); @@ -206,7 +238,9 @@ fn test_instantiate_with_collection_info_and_extension() { fn test_instantiate_with_minimal_collection_info_and_extension() { let mut deps = mock_dependencies(); let contract = Cw721OnchainExtensions::default(); - + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); let collection_info_extension_msg = Some(CollectionExtensionMsg { description: Some("description".to_string()), image: Some("https://moonphases.org".to_string()), @@ -219,11 +253,11 @@ fn test_instantiate_with_minimal_collection_info_and_extension() { name: CONTRACT_NAME.to_string(), symbol: SYMBOL.to_string(), collection_info_extension: collection_info_extension_msg, - minter: Some(String::from(MINTER_ADDR)), - creator: Some(String::from(CREATOR_ADDR)), - withdraw_address: Some(String::from(CREATOR_ADDR)), + minter: Some(minter.to_string()), + creator: Some(creator.to_string()), + withdraw_address: Some(creator.to_string()), }; - let info = mock_info("creator", &[]); + let info = addrs.info("creator"); let env = mock_env(); // we can just call .unwrap() to assert this was a success @@ -241,9 +275,9 @@ fn test_instantiate_with_minimal_collection_info_and_extension() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(MINTER_ADDR)), minter_ownership.owner); + assert_eq!(Some(minter), minter_ownership.owner); let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); - assert_eq!(Some(Addr::unchecked(CREATOR_ADDR)), creator_ownership.owner); + assert_eq!(Some(creator), creator_ownership.owner); let info = contract .query_collection_info_and_extension(deps.as_ref()) .unwrap(); @@ -269,7 +303,10 @@ fn test_instantiate_with_minimal_collection_info_and_extension() { #[test] fn test_mint() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id1 = "petrify".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { @@ -281,7 +318,7 @@ fn test_mint() { // invalid token uri let env = mock_env(); - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info("minter"); let err = contract .execute(deps.as_mut(), &env, &info_minter, mint_msg) .unwrap_err(); @@ -291,7 +328,7 @@ fn test_mint() { ); // random cannot mint - let info_random = mock_info("random", &[]); + let info_random = addrs.info("random"); let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id1.clone(), @@ -305,7 +342,7 @@ fn test_mint() { assert_eq!(err, Cw721ContractError::NotMinter {}); // minter can mint - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info("minter"); let _ = contract .execute(deps.as_mut(), &env, &info_minter, mint_msg) .unwrap(); @@ -351,9 +388,8 @@ fn test_mint() { extension: None, }; - let allowed = mock_info(MINTER_ADDR, &[]); let err = contract - .execute(deps.as_mut(), &mock_env(), &allowed, mint_msg2) + .execute(deps.as_mut(), &mock_env(), &info_minter, mint_msg2) .unwrap_err(); assert_eq!(err, Cw721ContractError::Claimed {}); @@ -472,7 +508,10 @@ fn test_mint() { #[test] fn test_update_nft_info() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id = "1".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { @@ -483,7 +522,7 @@ fn test_update_nft_info() { }; // mint nft - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info("minter"); let env = mock_env(); contract .execute(deps.as_mut(), &env, &info_minter, mint_msg) @@ -544,7 +583,7 @@ fn test_update_nft_info() { youtube_url: None, }), }; - let info_other = mock_info("other", &[]); + let info_other = addrs.info("other"); let err = contract .execute( deps.as_mut(), @@ -556,11 +595,12 @@ fn test_update_nft_info() { assert_eq!(err, Cw721ContractError::NotCreator {}); // creator updates nft info + let creator_info = addrs.info("creator"); contract .execute( deps.as_mut(), &env, - &mock_info(CREATOR_ADDR, &[]), + &creator_info, update_msg_without_extension, ) .unwrap(); @@ -579,7 +619,7 @@ fn test_update_nft_info() { .execute( deps.as_mut(), &env, - &mock_info(CREATOR_ADDR, &[]), + &creator_info, update_msg_only_extension, ) .unwrap(); @@ -609,7 +649,10 @@ fn test_mint_with_metadata() { // case 1: mint with valid metadata { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id = "1".to_string(); let token_uri = "ipfs://foo.bar".to_string(); @@ -635,7 +678,7 @@ fn test_mint_with_metadata() { extension: Some(valid_extension_msg.clone()), }; - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info("minter"); let env = mock_env(); contract .execute(deps.as_mut(), &env, &info_minter, mint_msg) @@ -736,11 +779,14 @@ fn test_mint_with_metadata() { // case 2: mint with invalid metadata { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id = "1".to_string(); let token_uri = "ipfs://foo.bar".to_string(); - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info("minter"); let env = mock_env(); let valid_extension_msg = NftExtensionMsg { @@ -893,7 +939,10 @@ fn test_mint_with_metadata() { #[test] fn test_update_collection_info() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let update_collection_info_msg = Cw721ExecuteMsg::UpdateCollectionInfo { collection_info: CollectionInfoMsg { @@ -904,7 +953,7 @@ fn test_update_collection_info() { }; // Creator can update collection info - let creator_info = mock_info(CREATOR_ADDR, &[]); + let creator_info = addrs.info("creator"); let _ = contract .execute( deps.as_mut(), @@ -916,13 +965,14 @@ fn test_update_collection_info() { // Update the owner to "random". The new owner should be able to // mint new tokens, the old one should not. + let random = addrs.addr("random"); contract .execute( deps.as_mut(), &mock_env(), &creator_info, Cw721ExecuteMsg::UpdateCreatorOwnership(Action::TransferOwnership { - new_owner: "random".to_string(), + new_owner: random.to_string(), expiry: None, }), ) @@ -944,14 +994,14 @@ fn test_update_collection_info() { assert_eq!( ownership, Ownership:: { - owner: Some(Addr::unchecked(CREATOR_ADDR)), - pending_owner: Some(Addr::unchecked("random")), + owner: Some(creator), + pending_owner: Some(random), pending_expiry: None, } ); // Accept the ownership transfer. - let random_info = mock_info("random", &[]); + let random_info = addrs.info("random"); contract .execute( deps.as_mut(), @@ -1007,7 +1057,10 @@ fn test_update_collection_info() { #[test] fn test_update_minter() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id = "petrify".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); @@ -1020,20 +1073,21 @@ fn test_update_minter() { }; // Minter can mint - let current_minter_info = mock_info(MINTER_ADDR, &[]); + let current_minter_info = addrs.info("minter"); let _ = contract .execute(deps.as_mut(), &mock_env(), ¤t_minter_info, mint_msg) .unwrap(); // Update the owner to "random". The new owner should be able to // mint new tokens, the old one should not. + let random = addrs.addr("random"); contract .execute( deps.as_mut(), &mock_env(), ¤t_minter_info, Cw721ExecuteMsg::UpdateMinterOwnership(Action::TransferOwnership { - new_owner: "random".to_string(), + new_owner: random.to_string(), expiry: None, }), ) @@ -1055,14 +1109,14 @@ fn test_update_minter() { assert_eq!( ownership, Ownership:: { - owner: Some(Addr::unchecked(MINTER_ADDR)), - pending_owner: Some(Addr::unchecked("random")), + owner: Some(minter), + pending_owner: Some(random), pending_expiry: None, } ); // Accept the ownership transfer. - let new_minter_info = mock_info("random", &[]); + let new_minter_info = addrs.info("random"); contract .execute( deps.as_mut(), @@ -1112,14 +1166,17 @@ fn test_update_minter() { #[test] fn test_burn() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); let token_id = "petrify".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: MINTER_ADDR.to_string(), + owner: minter.to_string(), token_uri: Some(token_uri), extension: None, }; @@ -1127,13 +1184,13 @@ fn test_burn() { let burn_msg = Cw721ExecuteMsg::Burn { token_id }; // mint some NFT - let allowed = mock_info(MINTER_ADDR, &[]); + let allowed = message_info(&minter, &[]); let _ = contract .execute(deps.as_mut(), &mock_env(), &allowed, mint_msg) .unwrap(); // random not allowed to burn - let random = mock_info("random", &[]); + let random = message_info(&deps.api.addr_make("random"), &[]); let env = mock_env(); let err = contract .execute(deps.as_mut(), &env, &random, burn_msg.clone()) @@ -1164,52 +1221,55 @@ fn test_burn() { #[test] fn test_transfer_nft() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // Mint a token let token_id = "melt".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - + let venus = addrs.addr("venus"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("venus"), + owner: venus.to_string(), token_uri: Some(token_uri), extension: None, }; - let minter = mock_info(MINTER_ADDR, &[]); + let minter_info = message_info(&minter, &[]); contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg) + .execute(deps.as_mut(), &mock_env(), &minter_info, mint_msg) .unwrap(); // random cannot transfer - let random = mock_info("random", &[]); + let random = addrs.addr("random"); + let random_info = addrs.info("random"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("random"), + recipient: random.to_string(), token_id: token_id.clone(), }; let err = contract - .execute(deps.as_mut(), &mock_env(), &random, transfer_msg) + .execute(deps.as_mut(), &mock_env(), &random_info, transfer_msg) .unwrap_err(); assert_eq!(err, Cw721ContractError::Ownership(OwnershipError::NotOwner)); // owner can - let random = mock_info("venus", &[]); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("random"), + recipient: random.to_string(), token_id: token_id.clone(), }; let res = contract - .execute(deps.as_mut(), &mock_env(), &random, transfer_msg) + .execute(deps.as_mut(), &mock_env(), &random_info, transfer_msg) .unwrap(); assert_eq!( res, Response::new() .add_attribute("action", "transfer_nft") - .add_attribute("sender", "venus") + .add_attribute("sender", venus.to_string()) .add_attribute("recipient", "random") .add_attribute("token_id", token_id) ); @@ -1218,22 +1278,24 @@ fn test_transfer_nft() { #[test] fn test_send_nft() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // Mint a token let token_id = "melt".to_string(); let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - + let venus = addrs.addr("venus"); let mint_msg = Cw721ExecuteMsg::Mint { token_id: token_id.clone(), - owner: String::from("venus"), + owner: venus.to_string(), token_uri: Some(token_uri), extension: None, }; - let minter = mock_info(MINTER_ADDR, &[]); contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg) + .execute(deps.as_mut(), &mock_env(), &addrs.info("minter"), mint_msg) .unwrap(); let msg = to_json_binary("You now have the melting power").unwrap(); @@ -1244,20 +1306,23 @@ fn test_send_nft() { msg: msg.clone(), }; - let random = mock_info("random", &[]); let err = contract - .execute(deps.as_mut(), &mock_env(), &random, send_msg.clone()) + .execute( + deps.as_mut(), + &mock_env(), + &addrs.info("random"), + send_msg.clone(), + ) .unwrap_err(); assert_eq!(err, Cw721ContractError::Ownership(OwnershipError::NotOwner)); // but owner can - let random = mock_info("venus", &[]); let res = contract - .execute(deps.as_mut(), &mock_env(), &random, send_msg) + .execute(deps.as_mut(), &mock_env(), &addrs.info("venus"), send_msg) .unwrap(); let payload = Cw721ReceiveMsg { - sender: String::from("venus"), + sender: venus.to_string(), token_id: token_id.clone(), msg, }; @@ -1275,7 +1340,7 @@ fn test_send_nft() { Response::new() .add_message(expected) .add_attribute("action", "send_nft") - .add_attribute("sender", "venus") + .add_attribute("sender", venus.to_string()) .add_attribute("recipient", "another_contract") .add_attribute("token_id", token_id) ); @@ -1284,7 +1349,10 @@ fn test_send_nft() { #[test] fn test_approve_revoke() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // Mint a token let token_id = "grow".to_string(); @@ -1297,9 +1365,9 @@ fn test_approve_revoke() { extension: None, }; - let minter = mock_info(MINTER_ADDR, &[]); + let minter_info = addrs.info("minter"); contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg) + .execute(deps.as_mut(), &mock_env(), &minter_info, mint_msg) .unwrap(); // token owner shows in approval query @@ -1328,15 +1396,15 @@ fn test_approve_revoke() { token_id: token_id.clone(), expires: None, }; - let owner = mock_info("demeter", &[]); + let owner_info = addrs.info("demeter"); let res = contract - .execute(deps.as_mut(), &mock_env(), &owner, approve_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, approve_msg) .unwrap(); assert_eq!( res, Response::new() .add_attribute("action", "approve") - .add_attribute("sender", "demeter") + .add_attribute("sender", addrs.addr("demeter").to_string()) .add_attribute("spender", "random") .add_attribute("token_id", token_id.clone()) ); @@ -1362,13 +1430,15 @@ fn test_approve_revoke() { ); // random can now transfer - let random = mock_info("random", &[]); + let random = addrs.addr("random"); + let random_info = addrs.info("random"); + let person = addrs.addr("person"); let transfer_msg = Cw721ExecuteMsg::TransferNft { - recipient: String::from("person"), + recipient: person.to_string(), token_id: token_id.clone(), }; contract - .execute(deps.as_mut(), &mock_env(), &random, transfer_msg) + .execute(deps.as_mut(), &mock_env(), &random_info, transfer_msg) .unwrap(); // Approvals are removed / cleared @@ -1385,20 +1455,20 @@ fn test_approve_revoke() { assert_eq!( res, OwnerOfResponse { - owner: String::from("person"), + owner: person.to_string(), approvals: vec![], } ); // Approve, revoke, and check for empty, to test revoke let approve_msg = Cw721ExecuteMsg::Approve { - spender: String::from("random"), + spender: random.to_string(), token_id: token_id.clone(), expires: None, }; - let owner = mock_info("person", &[]); + let owner_info = addrs.info("person"); contract - .execute(deps.as_mut(), &mock_env(), &owner, approve_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, approve_msg) .unwrap(); let revoke_msg = Cw721ExecuteMsg::Revoke { @@ -1406,7 +1476,7 @@ fn test_approve_revoke() { token_id, }; contract - .execute(deps.as_mut(), &mock_env(), &owner, revoke_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, revoke_msg) .unwrap(); // Approvals are now removed / cleared @@ -1419,7 +1489,7 @@ fn test_approve_revoke() { assert_eq!( res, OwnerOfResponse { - owner: String::from("person"), + owner: person.to_string(), approvals: vec![], } ); @@ -1428,7 +1498,10 @@ fn test_approve_revoke() { #[test] fn test_approve_all_revoke_all() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // Mint a couple tokens (from the same owner) let token_id1 = "grow1".to_string(); @@ -1444,9 +1517,9 @@ fn test_approve_all_revoke_all() { extension: None, }; - let minter = mock_info(MINTER_ADDR, &[]); + let minter_info = addrs.info("minter"); contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg1) + .execute(deps.as_mut(), &mock_env(), &minter_info, mint_msg1) .unwrap(); let mint_msg2 = Cw721ExecuteMsg::Mint { @@ -1458,7 +1531,7 @@ fn test_approve_all_revoke_all() { let env = mock_env(); contract - .execute(deps.as_mut(), &env, &minter, mint_msg2) + .execute(deps.as_mut(), &env, &minter_info, mint_msg2) .unwrap(); // paginate the token_ids @@ -1478,26 +1551,26 @@ fn test_approve_all_revoke_all() { operator: String::from("random"), expires: None, }; - let owner = mock_info("demeter", &[]); + let owner_info = addrs.info("demeter"); let res = contract - .execute(deps.as_mut(), &mock_env(), &owner, approve_all_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, approve_all_msg) .unwrap(); assert_eq!( res, Response::new() .add_attribute("action", "approve_all") - .add_attribute("sender", "demeter") + .add_attribute("sender", addrs.addr("demeter").to_string()) .add_attribute("operator", "random") ); // random can now transfer - let random = mock_info("random", &[]); + let random_info = addrs.info("random"); let transfer_msg = Cw721ExecuteMsg::TransferNft { recipient: String::from("person"), token_id: token_id1, }; contract - .execute(deps.as_mut(), &mock_env(), &random, transfer_msg) + .execute(deps.as_mut(), &mock_env(), &random_info, transfer_msg) .unwrap(); // random can now send @@ -1514,7 +1587,7 @@ fn test_approve_all_revoke_all() { msg: to_json_binary(&msg).unwrap(), }; contract - .execute(deps.as_mut(), &mock_env(), &random, send_msg) + .execute(deps.as_mut(), &mock_env(), &random_info, send_msg) .unwrap(); // Approve_all, revoke_all, and check for empty, to test revoke_all @@ -1523,9 +1596,9 @@ fn test_approve_all_revoke_all() { expires: None, }; // person is now the owner of the tokens - let owner = mock_info("person", &[]); + let owner_info = addrs.info("person"); contract - .execute(deps.as_mut(), &mock_env(), &owner, approve_all_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, approve_all_msg) .unwrap(); // query for operator should return approval @@ -1533,8 +1606,8 @@ fn test_approve_all_revoke_all() { .query_operator( deps.as_ref(), &mock_env(), - String::from("person"), - String::from("operator"), + addrs.addr("person").to_string(), + addrs.addr("operator").to_string(), true, ) .unwrap(); @@ -1542,7 +1615,7 @@ fn test_approve_all_revoke_all() { res, OperatorResponse { approval: Approval { - spender: Addr::unchecked("operator"), + spender: addrs.addr("operator"), expires: Expiration::Never {} } } @@ -1557,7 +1630,7 @@ fn test_approve_all_revoke_all() { true, ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } @@ -1587,9 +1660,9 @@ fn test_approve_all_revoke_all() { operator: String::from("buddy"), expires: Some(buddy_expires), }; - let owner = mock_info("person", &[]); + let owner_info = addrs.info("person"); contract - .execute(deps.as_mut(), &mock_env(), &owner, approve_all_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, approve_all_msg) .unwrap(); // and paginate queries @@ -1636,7 +1709,7 @@ fn test_approve_all_revoke_all() { operator: String::from("operator"), }; contract - .execute(deps.as_mut(), &mock_env(), &owner, revoke_all_msg) + .execute(deps.as_mut(), &mock_env(), &owner_info, revoke_all_msg) .unwrap(); // query for operator should return error @@ -1648,7 +1721,7 @@ fn test_approve_all_revoke_all() { true, ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } @@ -1698,7 +1771,7 @@ fn test_approve_all_revoke_all() { ); match res { - Err(StdError::NotFound { kind }) => assert_eq!(kind, "Approval not found"), + Err(StdError::NotFound { kind, .. }) => assert_eq!(kind, "Approval not found"), _ => panic!("Unexpected error"), } } @@ -1706,25 +1779,20 @@ fn test_approve_all_revoke_all() { #[test] fn test_set_withdraw_address() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // other than creator cant set let err = contract - .set_withdraw_address( - deps.as_mut(), - &Addr::unchecked(MINTER_ADDR), - "foo".to_string(), - ) + .set_withdraw_address(deps.as_mut(), &minter, "foo".to_string()) .unwrap_err(); assert_eq!(err, Cw721ContractError::Ownership(OwnershipError::NotOwner)); // creator can set contract - .set_withdraw_address( - deps.as_mut(), - &Addr::unchecked(CREATOR_ADDR), - "foo".to_string(), - ) + .set_withdraw_address(deps.as_mut(), &creator, "foo".to_string()) .unwrap(); let withdraw_address = contract @@ -1738,30 +1806,29 @@ fn test_set_withdraw_address() { #[test] fn test_remove_withdraw_address() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // other than creator cant remove let err = contract - .remove_withdraw_address(deps.as_mut().storage, &Addr::unchecked(MINTER_ADDR)) + .remove_withdraw_address(deps.as_mut().storage, &minter) .unwrap_err(); assert_eq!(err, Cw721ContractError::Ownership(OwnershipError::NotOwner)); // no withdraw address set yet let err = contract - .remove_withdraw_address(deps.as_mut().storage, &Addr::unchecked(CREATOR_ADDR)) + .remove_withdraw_address(deps.as_mut().storage, &creator) .unwrap_err(); assert_eq!(err, Cw721ContractError::NoWithdrawAddress {}); // set and remove contract - .set_withdraw_address( - deps.as_mut(), - &Addr::unchecked(CREATOR_ADDR), - "foo".to_string(), - ) + .set_withdraw_address(deps.as_mut(), &creator, "foo".to_string()) .unwrap(); contract - .remove_withdraw_address(deps.as_mut().storage, &Addr::unchecked(CREATOR_ADDR)) + .remove_withdraw_address(deps.as_mut().storage, &creator) .unwrap(); assert!(!contract .config @@ -1770,11 +1837,7 @@ fn test_remove_withdraw_address() { // test that we can set again contract - .set_withdraw_address( - deps.as_mut(), - &Addr::unchecked(CREATOR_ADDR), - "foo".to_string(), - ) + .set_withdraw_address(deps.as_mut(), &creator, "foo".to_string()) .unwrap(); let withdraw_address = contract .config @@ -1787,32 +1850,34 @@ fn test_remove_withdraw_address() { #[test] fn test_withdraw_funds() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); // no withdraw address set let err = contract - .withdraw_funds(deps.as_mut().storage, &Coin::new(100, "uark")) + .withdraw_funds(deps.as_mut().storage, &Coin::new(100u32, "uark")) .unwrap_err(); assert_eq!(err, Cw721ContractError::NoWithdrawAddress {}); // set and withdraw by non-creator contract - .set_withdraw_address( - deps.as_mut(), - &Addr::unchecked(CREATOR_ADDR), - "foo".to_string(), - ) + .set_withdraw_address(deps.as_mut(), &creator, "foo".to_string()) .unwrap(); contract - .withdraw_funds(deps.as_mut().storage, &Coin::new(100, "uark")) + .withdraw_funds(deps.as_mut().storage, &Coin::new(100u32, "uark")) .unwrap(); } #[test] fn query_tokens_by_owner() { let mut deps = mock_dependencies(); - let contract = setup_contract(deps.as_mut()); - let minter = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let creator = addrs.addr("creator"); + let minter = addrs.addr("minter"); + let contract = setup_contract(deps.as_mut(), &creator, &minter); + let minter_info = addrs.info("minter"); // Mint a couple tokens (from the same owner) let token_id1 = "grow1".to_string(); @@ -1828,7 +1893,7 @@ fn query_tokens_by_owner() { extension: None, }; contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg) + .execute(deps.as_mut(), &mock_env(), &minter_info, mint_msg) .unwrap(); let mint_msg = Cw721ExecuteMsg::Mint { @@ -1838,7 +1903,7 @@ fn query_tokens_by_owner() { extension: None, }; contract - .execute(deps.as_mut(), &mock_env(), &minter, mint_msg) + .execute(deps.as_mut(), &mock_env(), &minter_info, mint_msg) .unwrap(); let mint_msg = Cw721ExecuteMsg::Mint { @@ -1849,7 +1914,7 @@ fn query_tokens_by_owner() { }; let env = mock_env(); contract - .execute(deps.as_mut(), &env, &minter, mint_msg) + .execute(deps.as_mut(), &env, &minter_info, mint_msg) .unwrap(); // get all tokens in order: diff --git a/packages/cw721/src/testing/multi_tests.rs b/packages/cw721/src/testing/multi_tests.rs index 24bf333eb..bac51b32f 100644 --- a/packages/cw721/src/testing/multi_tests.rs +++ b/packages/cw721/src/testing/multi_tests.rs @@ -2,8 +2,8 @@ use crate::{ error::Cw721ContractError, extension::Cw721OnchainExtensions, msg::{ - Cw721ExecuteMsg, Cw721InstantiateMsg, Cw721MigrateMsg, Cw721QueryMsg, MinterResponse, - NumTokensResponse, OwnerOfResponse, + Cw721ExecuteMsg, Cw721InstantiateMsg, Cw721MigrateMsg, Cw721QueryMsg, NumTokensResponse, + OwnerOfResponse, }, state::{NftExtension, Trait}, traits::{Cw721Execute, Cw721Query}, @@ -11,12 +11,11 @@ use crate::{ DefaultOptionalNftExtension, DefaultOptionalNftExtensionMsg, NftExtensionMsg, }; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, QuerierWrapper, Response, - WasmMsg, + Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, QuerierWrapper, Response, }; use cw721_016::NftInfoResponse; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; -use cw_ownable::{Ownership, OwnershipError}; +use cw_ownable::OwnershipError; use cw_utils::Expiration; use url::ParseError; @@ -72,63 +71,6 @@ fn cw721_base_latest_contract() -> Box> { Box::new(contract) } -fn cw721_base_015_contract() -> Box> { - use cw721_base_015 as v15; - let contract = ContractWrapper::new( - v15::entry::execute, - v15::entry::instantiate, - v15::entry::query, - ); - Box::new(contract) -} - -fn cw721_base_016_contract() -> Box> { - use cw721_base_016 as v16; - let contract = ContractWrapper::new( - v16::entry::execute, - v16::entry::instantiate, - v16::entry::query, - ); - Box::new(contract) -} - -fn cw721_base_017_contract() -> Box> { - use cw721_base_017 as v17; - let contract = ContractWrapper::new( - v17::entry::execute, - v17::entry::instantiate, - v17::entry::query, - ); - Box::new(contract) -} - -fn cw721_base_018_contract() -> Box> { - use cw721_base_018 as v18; - let contract = ContractWrapper::new( - v18::entry::execute, - v18::entry::instantiate, - v18::entry::query, - ); - Box::new(contract) -} - -fn query_owner(querier: QuerierWrapper, cw721: &Addr, token_id: String) -> Addr { - let resp: OwnerOfResponse = querier - .query_wasm_smart( - cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::OwnerOf { - token_id, - include_expired: None, - }, - ) - .unwrap(); - Addr::unchecked(resp.owner) -} - fn query_nft_info( querier: QuerierWrapper, cw721: &Addr, @@ -148,46 +90,6 @@ fn query_nft_info( .unwrap() } -fn mint_transfer_and_burn(app: &mut App, cw721: Addr, sender: Addr, token_id: String) { - app.execute_contract( - sender.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: token_id.clone(), - owner: sender.to_string(), - token_uri: None, - extension: Empty::default(), - }, - &[], - ) - .unwrap(); - - let owner = query_owner(app.wrap(), &cw721, token_id.clone()); - assert_eq!(owner, sender.to_string()); - - app.execute_contract( - sender, - cw721.clone(), - &Cw721ExecuteMsg::::TransferNft { - recipient: "burner".to_string(), - token_id: token_id.clone(), - }, - &[], - ) - .unwrap(); - - let owner = query_owner(app.wrap(), &cw721, token_id.clone()); - assert_eq!(owner, "burner".to_string()); - - app.execute_contract( - Addr::unchecked("burner"), - cw721, - &Cw721ExecuteMsg::::Burn { token_id }, - &[], - ) - .unwrap(); -} - #[test] fn test_operator() { // --- setup --- @@ -381,1088 +283,6 @@ fn test_operator() { assert_eq!(err, Cw721ContractError::Ownership(OwnershipError::NotOwner)); } -/// Instantiates a 0.16 version of this contract and tests that tokens -/// can be minted, transferred, and burnred after migration. -#[test] -fn test_migration_legacy_to_latest() { - // v0.15 migration by using existing minter addr - { - use cw721_base_015 as v15; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_016 = app.store_code(cw721_base_015_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_016, - legacy_creator_and_minter.clone(), - &v15::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: None, - creator: None, - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // non-minter user cant mint - let other = Addr::unchecked(OTHER_ADDR); - let err: Cw721ContractError = app - .execute_contract( - other.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: other.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // legacy minter can still mint - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v15::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, legacy_creator_and_minter.to_string()); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!( - minter_ownership.owner, - Some(legacy_creator_and_minter.clone()) - ); - - // check creator ownership query works - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(legacy_creator_and_minter)); - } - // v0.15 migration by providing new creator and minter addr - { - use cw721_base_015 as v15; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_015 = app.store_code(cw721_base_015_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_015, - legacy_creator_and_minter.clone(), - &v15::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: Some(MINTER_ADDR.to_string()), - creator: Some(CREATOR_ADDR.to_string()), - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // legacy minter user cant mint - let err: Cw721ContractError = app - .execute_contract( - legacy_creator_and_minter.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: legacy_creator_and_minter.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // new minter can mint - let minter = Addr::unchecked(MINTER_ADDR); - mint_transfer_and_burn(&mut app, cw721.clone(), minter.clone(), "1".to_string()); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v15::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, minter.to_string()); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!(minter_ownership.owner, Some(minter)); - - // check creator ownership query works - let creator = Addr::unchecked(CREATOR_ADDR); - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(creator)); - } - // v0.16 migration by using existing minter addr - { - use cw721_base_016 as v16; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_016 = app.store_code(cw721_base_016_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_016, - legacy_creator_and_minter.clone(), - &v16::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: None, - creator: None, - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // non-minter user cant mint - let other = Addr::unchecked(OTHER_ADDR); - let err: Cw721ContractError = app - .execute_contract( - other.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: other.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // legacy minter can still mint - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v16::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, legacy_creator_and_minter.to_string()); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!( - minter_ownership.owner, - Some(legacy_creator_and_minter.clone()) - ); - - // check creator ownership query works - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(legacy_creator_and_minter)); - } - // v0.16 migration by providing new creator and minter addr - { - use cw721_base_016 as v16; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_016 = app.store_code(cw721_base_016_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_016, - legacy_creator_and_minter.clone(), - &v16::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: Some(MINTER_ADDR.to_string()), - creator: Some(CREATOR_ADDR.to_string()), - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // legacy minter user cant mint - let err: Cw721ContractError = app - .execute_contract( - legacy_creator_and_minter.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: legacy_creator_and_minter.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // new minter can mint - let minter = Addr::unchecked(MINTER_ADDR); - mint_transfer_and_burn(&mut app, cw721.clone(), minter.clone(), "1".to_string()); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v16::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, minter.to_string()); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!(minter_ownership.owner, Some(minter)); - - // check creator ownership query works - let creator = Addr::unchecked(CREATOR_ADDR); - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(creator)); - } - // v0.17 migration by using existing minter addr - { - use cw721_base_017 as v17; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_017 = app.store_code(cw721_base_017_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_017, - legacy_creator_and_minter.clone(), - &v17::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: None, - creator: None, - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // non-minter user cant mint - let other = Addr::unchecked(OTHER_ADDR); - let err: Cw721ContractError = app - .execute_contract( - other.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: other.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // legacy minter can still mint - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v17::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!( - minter_ownership.owner, - Some(legacy_creator_and_minter.clone()) - ); - - // check creator ownership query works - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(legacy_creator_and_minter)); - } - // v0.17 migration by providing new creator and minter addr - { - use cw721_base_017 as v17; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_017 = app.store_code(cw721_base_017_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_017, - legacy_creator_and_minter.clone(), - &v17::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: Some(MINTER_ADDR.to_string()), - creator: Some(CREATOR_ADDR.to_string()), - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // legacy minter user cant mint - let err: Cw721ContractError = app - .execute_contract( - legacy_creator_and_minter.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: legacy_creator_and_minter.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // new minter can mint - let minter = Addr::unchecked(MINTER_ADDR); - mint_transfer_and_burn(&mut app, cw721.clone(), minter.clone(), "1".to_string()); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v17::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!(minter_ownership.owner, Some(minter)); - - // check creator ownership query works - let creator = Addr::unchecked(CREATOR_ADDR); - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(creator)); - } - // v0.18 migration by using existing minter addr - { - use cw721_base_018 as v18; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_018 = app.store_code(cw721_base_018_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_018, - legacy_creator_and_minter.clone(), - &v18::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: None, - creator: None, - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // non-minter user cant mint - let other = Addr::unchecked(OTHER_ADDR); - let err: Cw721ContractError = app - .execute_contract( - other.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: other.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // legacy minter can still mint - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v18::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(legacy_creator_and_minter.to_string())); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!( - minter_ownership.owner, - Some(legacy_creator_and_minter.clone()) - ); - - // check creator ownership query works - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(legacy_creator_and_minter)); - } - // v0.18 migration by providing new creator and minter addr - { - use cw721_base_018 as v18; - let mut app = App::default(); - let admin = Addr::unchecked("admin"); - - let code_id_018 = app.store_code(cw721_base_018_contract()); - let code_id_latest = app.store_code(cw721_base_latest_contract()); - - let legacy_creator_and_minter = Addr::unchecked("legacy_creator_and_minter"); - - let cw721 = app - .instantiate_contract( - code_id_018, - legacy_creator_and_minter.clone(), - &v18::InstantiateMsg { - name: "collection".to_string(), - symbol: "symbol".to_string(), - minter: legacy_creator_and_minter.to_string(), - }, - &[], - "cw721-base", - Some(admin.to_string()), - ) - .unwrap(); - - mint_transfer_and_burn( - &mut app, - cw721.clone(), - legacy_creator_and_minter.clone(), - "1".to_string(), - ); - - // migrate - app.execute( - admin, - WasmMsg::Migrate { - contract_addr: cw721.to_string(), - new_code_id: code_id_latest, - msg: to_json_binary(&Cw721MigrateMsg::WithUpdate { - minter: Some(MINTER_ADDR.to_string()), - creator: Some(CREATOR_ADDR.to_string()), - }) - .unwrap(), - } - .into(), - ) - .unwrap(); - - // legacy minter user cant mint - let err: Cw721ContractError = app - .execute_contract( - legacy_creator_and_minter.clone(), - cw721.clone(), - &Cw721ExecuteMsg::::Mint { - token_id: "1".to_string(), - owner: legacy_creator_and_minter.to_string(), - token_uri: Some("ipfs://new.uri".to_string()), - extension: Empty::default(), - }, - &[], - ) - .unwrap_err() - .downcast() - .unwrap(); - assert_eq!(err, Cw721ContractError::NotMinter {}); - - // new minter can mint - let minter = Addr::unchecked(MINTER_ADDR); - mint_transfer_and_burn(&mut app, cw721.clone(), minter.clone(), "1".to_string()); - - // check new mint query response works. - #[allow(deprecated)] - let m: MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check that the new response is backwards compatable when minter - // is not None. - #[allow(deprecated)] - let m: v18::MinterResponse = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::Minter {}, - ) - .unwrap(); - assert_eq!(m.minter, Some(minter.to_string())); - - // check minter ownership query works - let minter_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetMinterOwnership {}, - ) - .unwrap(); - assert_eq!(minter_ownership.owner, Some(minter)); - - // check creator ownership query works - let creator = Addr::unchecked(CREATOR_ADDR); - let creator_ownership: Ownership = app - .wrap() - .query_wasm_smart( - &cw721, - &Cw721QueryMsg::< - DefaultOptionalNftExtension, - DefaultOptionalCollectionExtension, - Empty, - >::GetCreatorOwnership {}, - ) - .unwrap(); - assert_eq!(creator_ownership.owner, Some(creator)); - } -} - /// Test backward compatibility using instantiate msg from a 0.16 version on latest contract. /// This ensures existing 3rd party contracts doesnt need to update as well. #[test] diff --git a/packages/cw721/src/testing/unit_tests.rs b/packages/cw721/src/testing/unit_tests.rs index b93510ecd..d1718c4af 100644 --- a/packages/cw721/src/testing/unit_tests.rs +++ b/packages/cw721/src/testing/unit_tests.rs @@ -2,10 +2,9 @@ use crate::{ error::Cw721ContractError, extension::Cw721OnchainExtensions, msg::{ - CollectionExtensionMsg, CollectionInfoAndExtensionResponse, CollectionInfoMsg, - Cw721ExecuteMsg, Cw721InstantiateMsg, NftExtensionMsg, RoyaltyInfoResponse, + CollectionExtensionMsg, CollectionInfoMsg, Cw721ExecuteMsg, Cw721InstantiateMsg, + NftExtensionMsg, RoyaltyInfoResponse, }, - query::MAX_LIMIT, state::{ NftExtension, Trait, CREATOR, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_ROYALTY_SHARE_DELTA_PCT, MAX_ROYALTY_SHARE_PCT, MINTER, @@ -14,12 +13,12 @@ use crate::{ CollectionExtension, RoyaltyInfo, }; use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, + testing::{mock_dependencies, mock_env}, Addr, Api, Decimal, Timestamp, }; use cw2::ContractVersion; use cw_ownable::Action; -use cw_storage_plus::Item; +use unit_tests::contract_tests::MockAddrFactory; use unit_tests::multi_tests::{CREATOR_ADDR, MINTER_ADDR, OTHER_ADDR}; use super::*; @@ -27,13 +26,13 @@ use super::*; #[test] fn test_instantiation() { let mut deps = mock_dependencies(); - + let mut addrs = MockAddrFactory::new(deps.api); // error on empty name let err = Cw721OnchainExtensions::default() .instantiate_with_version( deps.as_mut(), &mock_env(), - &mock_info("mr-t", &[]), + &addrs.info("mr-t"), Cw721InstantiateMsg { name: "".into(), symbol: "collection_symbol".into(), @@ -53,7 +52,7 @@ fn test_instantiation() { .instantiate_with_version( deps.as_mut(), &mock_env(), - &mock_info("mr-t", &[]), + &addrs.info("mr-t"), Cw721InstantiateMsg { name: "collection_name".into(), symbol: "".into(), @@ -72,7 +71,7 @@ fn test_instantiation() { .instantiate_with_version( deps.as_mut(), &mock_env(), - &mock_info("larry", &[]), + &addrs.info("larry"), Cw721InstantiateMsg { name: "collection_name".into(), symbol: "collection_symbol".into(), @@ -117,8 +116,8 @@ fn test_instantiation_with_proper_minter_and_creator() { // case 1: sender is used in case minter and creator is not set { let mut deps = mock_dependencies(); - - let info_minter_and_creator = mock_info("minter_and_creator", &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info_minter_and_creator = addrs.info("minter_and_creator"); Cw721OnchainExtensions::default() .instantiate_with_version( deps.as_mut(), @@ -145,8 +144,8 @@ fn test_instantiation_with_proper_minter_and_creator() { // case 2: minter and creator are set { let mut deps = mock_dependencies(); - - let info = mock_info(OTHER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info = addrs.info(OTHER_ADDR); Cw721OnchainExtensions::default() .instantiate_with_version( deps.as_mut(), @@ -173,8 +172,8 @@ fn test_instantiation_with_proper_minter_and_creator() { // case 3: sender is minter and creator is set { let mut deps = mock_dependencies(); - - let info = mock_info(MINTER_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info = addrs.info(MINTER_ADDR); Cw721OnchainExtensions::default() .instantiate_with_version( deps.as_mut(), @@ -201,8 +200,8 @@ fn test_instantiation_with_proper_minter_and_creator() { // case 4: sender is creator and minter is set { let mut deps = mock_dependencies(); - - let info = mock_info(CREATOR_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info = addrs.info(CREATOR_ADDR); Cw721OnchainExtensions::default() .instantiate_with_version( deps.as_mut(), @@ -233,8 +232,8 @@ fn test_instantiation_with_collection_info() { // case 1: extension set with proper data { let mut deps = mock_dependencies(); - - let info_creator = mock_info(CREATOR_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info_creator = addrs.info(CREATOR_ADDR); let extension = Some(CollectionExtension { description: "description".into(), image: "https://moonphases.org".to_string(), @@ -294,8 +293,8 @@ fn test_instantiation_with_collection_info() { { // invalid image let mut deps = mock_dependencies(); - - let info_creator = mock_info(CREATOR_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info_creator = addrs.info(CREATOR_ADDR); let extension_msg = Some(CollectionExtensionMsg { description: Some("description".into()), image: Some("invalid_url".to_string()), @@ -486,8 +485,9 @@ fn test_collection_info_update() { { // initialize contract let mut deps = mock_dependencies(); + let mut addrs = MockAddrFactory::new(deps.api); let env = mock_env(); - let info_creator = mock_info(CREATOR_ADDR, &[]); + let info_creator = addrs.info(CREATOR_ADDR); let expected_instantiated_extension = Some(CollectionExtension { description: "description".into(), image: "https://moonphases.org".to_string(), @@ -636,7 +636,7 @@ fn test_collection_info_update() { symbol: None, extension: Some(updated_extension_msg), }; - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_minter = addrs.info(MINTER_ADDR); contract .execute( deps.as_mut(), @@ -675,8 +675,9 @@ fn test_collection_info_update() { { // initialize contract let mut deps = mock_dependencies(); + let mut addrs = MockAddrFactory::new(deps.api); let env = mock_env(); - let info = mock_info(CREATOR_ADDR, &[]); + let info = addrs.info(CREATOR_ADDR); let instantiated_extension_msg = Some(CollectionExtensionMsg { description: Some("description".into()), image: Some("https://moonphases.org".to_string()), @@ -927,8 +928,9 @@ fn test_collection_info_update() { { // initialize contract let mut deps = mock_dependencies(); + let mut addrs = MockAddrFactory::new(deps.api); let env = mock_env(); - let info = mock_info(CREATOR_ADDR, &[]); + let info = addrs.info(CREATOR_ADDR); let instantiated_extension = Some(CollectionExtensionMsg { description: Some("description".into()), image: Some("https://moonphases.org".to_string()), @@ -982,7 +984,7 @@ fn test_collection_info_update() { symbol: Some("new_collection_symbol".into()), extension: Some(updated_extension_msg), }; - let info_other = mock_info(OTHER_ADDR, &[]); + let info_other = addrs.info(OTHER_ADDR); let err = contract .execute( deps.as_mut(), @@ -1043,9 +1045,10 @@ fn test_collection_info_update() { { // initialize contract let mut deps = mock_dependencies(); + let mut addrs = MockAddrFactory::new(deps.api); let env = mock_env(); - let info_creator = mock_info(CREATOR_ADDR, &[]); - let info_minter = mock_info(MINTER_ADDR, &[]); + let info_creator = addrs.info(CREATOR_ADDR); + let info_minter = addrs.info(MINTER_ADDR); let instantiated_extension = Some(CollectionExtensionMsg { description: Some("description".into()), image: Some("https://moonphases.org".to_string()), @@ -1132,8 +1135,8 @@ fn test_nft_mint() { { let mut deps = mock_dependencies(); let contract = Cw721OnchainExtensions::default(); - - let info = mock_info(CREATOR_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info = addrs.info(CREATOR_ADDR); let init_msg = Cw721InstantiateMsg { name: "collection_name".into(), symbol: "collection_symbol".into(), @@ -1183,7 +1186,7 @@ fn test_nft_mint() { .unwrap_err(); assert_eq!(err, Cw721ContractError::Claimed {}); // non-minter cant mint - let info = mock_info("john", &[]); + let info = addrs.info("john"); let exec_msg = Cw721ExecuteMsg::Mint { token_id: "Enterprise".to_string(), owner: "john".to_string(), @@ -1199,8 +1202,8 @@ fn test_nft_mint() { { let mut deps = mock_dependencies(); let contract = Cw721OnchainExtensions::default(); - - let info = mock_info(CREATOR_ADDR, &[]); + let mut addrs = MockAddrFactory::new(deps.api); + let info = addrs.info(CREATOR_ADDR); let init_msg = Cw721InstantiateMsg { name: "collection_name".into(), symbol: "collection_symbol".into(), @@ -1343,184 +1346,3 @@ fn test_nft_mint() { assert_eq!(result.len(), 2); } } - -#[test] -fn test_migrate_v16_onchain_metadata_contract() { - let mut deps = mock_dependencies(); - - // instantiate v16 onchain metadata contract - let env = mock_env(); - use cw721_metadata_onchain_016 as v16; - v16::entry::instantiate( - deps.as_mut(), - env.clone(), - mock_info("owner", &[]), - v16::InstantiateMsg { - name: "legacy_name".into(), - symbol: "legacy_symbol".into(), - minter: "legacy_minter".into(), - }, - ) - .unwrap(); - - // mint 200 NFTs before migration - using v16 contract - for i in 0..200 { - let info = mock_info("legacy_minter", &[]); - let msg = v16::ExecuteMsg::Mint(v16::MintMsg { - token_id: i.to_string(), - owner: "owner".into(), - token_uri: None, - extension: Some(v16::Metadata { - name: Some("name".to_string()), - description: Some("description".to_string()), - image: Some("image".to_string()), - ..cw721_metadata_onchain_016::Metadata::default() - }), - }); - v16::entry::execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - } - - // assert new data before migration: - // - minter, creator, and collection metadata throws NotFound Error - MINTER.item.load(deps.as_ref().storage).unwrap_err(); // cw_ownable in v16 is used for minter - let contract = Cw721OnchainExtensions::default(); - contract - .query_collection_info_and_extension(deps.as_ref()) - .unwrap_err(); - // - query in new minter and creator ownership store throws NotFound Error (in v16 it was stored outside cw_ownable, in dedicated "minter" store) - MINTER.get_ownership(deps.as_ref().storage).unwrap_err(); - CREATOR.get_ownership(deps.as_ref().storage).unwrap_err(); - // assert legacy data before migration: - // - version - let version = cw2::get_contract_version(deps.as_ref().storage) - .unwrap() - .version; - assert_eq!(version, "0.16.0"); - // - legacy minter is set - let legacy_minter_store: Item = Item::new("minter"); - let legacy_minter = legacy_minter_store.load(deps.as_ref().storage).unwrap(); - assert_eq!(legacy_minter, "legacy_minter"); - // - legacy collection metadata is set - let legacy_collection_info_store: Item = Item::new("nft_info"); - let legacy_collection_info = legacy_collection_info_store - .load(deps.as_ref().storage) - .unwrap(); - assert_eq!(legacy_collection_info.name, "legacy_name"); - assert_eq!(legacy_collection_info.symbol, "legacy_symbol"); - // 200 NFTs still exist - let all_tokens = contract - .query_all_tokens(deps.as_ref(), &env, None, Some(MAX_LIMIT)) - .unwrap(); - assert_eq!(all_tokens.tokens.len(), 200); - // NFTs have proper owner - for token_id in 0..200 { - let token = contract - .query_owner_of(deps.as_ref(), &env, token_id.to_string(), false) - .unwrap(); - assert_eq!(token.owner.as_str(), "owner"); - } - // check one nft - let token = contract - .query_nft_info(deps.as_ref().storage, "0".into()) - .unwrap(); - assert_eq!(token.token_uri, None); - assert_eq!( - token.extension, - Some(NftExtension { - name: Some("name".to_string()), - description: Some("description".to_string()), - image: Some("image".to_string()), - ..NftExtension::default() - }) - ); - - // migrate - Cw721OnchainExtensions::default() - .migrate( - deps.as_mut(), - env.clone(), - crate::msg::Cw721MigrateMsg::WithUpdate { - minter: None, - creator: None, - }, - "contract_name", - "new_contract_version", - ) - .unwrap(); - - // assert version has changed - let version = cw2::get_contract_version(deps.as_ref().storage) - .unwrap() - .version; - assert_eq!(version, "new_contract_version"); - - // assert minter ownership - let minter_ownership = MINTER - .get_ownership(deps.as_ref().storage) - .unwrap() - .owner - .map(|a| a.into_string()); - assert_eq!(minter_ownership, Some("legacy_minter".to_string())); - - // assert creator ownership - let creator_ownership = CREATOR - .get_ownership(deps.as_ref().storage) - .unwrap() - .owner - .map(|a| a.into_string()); - assert_eq!(creator_ownership, Some("legacy_minter".to_string())); - - // assert collection metadata - let collection_info = contract - .query_collection_info_and_extension(deps.as_ref()) - .unwrap(); - let legacy_contract_info = CollectionInfoAndExtensionResponse { - name: "legacy_name".to_string(), - symbol: "legacy_symbol".to_string(), - extension: None, - updated_at: env.block.time, - }; - assert_eq!(collection_info, legacy_contract_info); - - // assert tokens - let all_tokens = contract - .query_all_tokens(deps.as_ref(), &env, None, Some(MAX_LIMIT)) - .unwrap(); - assert_eq!(all_tokens.tokens.len(), 200); - // check one nft - let token = contract - .query_nft_info(deps.as_ref().storage, "0".into()) - .unwrap(); - assert_eq!(token.token_uri, None); - assert_eq!( - token.extension, - Some(NftExtension { - name: Some("name".to_string()), - description: Some("description".to_string()), - image: Some("image".to_string()), - ..NftExtension::default() - }) - ); - - // assert legacy data is still there (allowing backward migration in case of issues) - // - minter - let legacy_minter = legacy_minter_store.load(deps.as_ref().storage).unwrap(); - assert_eq!(legacy_minter, "legacy_minter"); - // - legacy collection metadata - let legacy_collection_info = legacy_collection_info_store - .load(deps.as_ref().storage) - .unwrap(); - assert_eq!(legacy_collection_info.name, "legacy_name"); - assert_eq!(legacy_collection_info.symbol, "legacy_symbol"); - // - tokens are unchanged/still exist - let all_tokens = contract - .query_all_tokens(deps.as_ref(), &env, None, Some(MAX_LIMIT)) - .unwrap(); - assert_eq!(all_tokens.tokens.len(), 200); - for token_id in 0..200 { - let token = contract - .query_owner_of(deps.as_ref(), &env, token_id.to_string(), false) - .unwrap(); - assert_eq!(token.owner.as_str(), "owner"); - } -} diff --git a/packages/cw721/src/traits.rs b/packages/cw721/src/traits.rs index 87f98e8af..83de4764d 100644 --- a/packages/cw721/src/traits.rs +++ b/packages/cw721/src/traits.rs @@ -723,7 +723,7 @@ pub trait Cw721Query< spender: String, include_expired_approval: bool, ) -> StdResult { - query_approval(deps, env, token_id, spender, include_expired_approval) + query_approval(deps, env, token_id, deps.api.addr_validate(&spender)?, include_expired_approval) } /// approvals returns all approvals owner given access to From 8a0f201b225dd2aaaa100d0bafa6ce564888fa90 Mon Sep 17 00:00:00 2001 From: mintthemoon Date: Mon, 12 Aug 2024 13:43:57 -0400 Subject: [PATCH 2/3] dependency updates --- Cargo.lock | 14 +++----------- Cargo.toml | 5 +++-- packages/cw721/Cargo.toml | 1 - 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d03c222d5..78a45efbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -517,6 +517,7 @@ dependencies = [ [[package]] name = "cw-address-like" version = "2.0.4" +source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" dependencies = [ "cosmwasm-std 2.1.3", ] @@ -559,6 +560,7 @@ dependencies = [ [[package]] name = "cw-ownable" version = "0.6.0" +source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" dependencies = [ "cosmwasm-schema 2.1.3", "cosmwasm-std 2.1.3", @@ -583,22 +585,13 @@ dependencies = [ [[package]] name = "cw-ownable-derive" version = "0.6.0" +source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] -[[package]] -name = "cw-paginate-storage" -version = "2.5.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git#2cac217cdea0e47dc32e9c9363175980774585d6" -dependencies = [ - "cosmwasm-std 1.5.7", - "cw-storage-plus 1.2.0", - "serde", -] - [[package]] name = "cw-storage-plus" version = "0.15.1" @@ -854,7 +847,6 @@ dependencies = [ "cosmwasm-std 2.1.3", "cw-multi-test", "cw-ownable 0.6.0", - "cw-paginate-storage", "cw-storage-plus 2.0.0", "cw-utils 2.0.0", "cw2 2.0.0", diff --git a/Cargo.toml b/Cargo.toml index 3df62af04..99f18abbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,9 @@ cw721-metadata-onchain-016 = { git = "https://github.com/CosmWasm/cw-nfts", tag cw721-base-017 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.17.0", package = "cw721-base" } # needed for testing legacy migration cw721-base-018 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.18.0", package = "cw721-base" } # needed for testing legacy migration cw-multi-test = { version = "^2.1", features = ["cosmwasm_2_0"] } -cw-ownable = { path = "../cw-plus-plus/packages/ownable" } # TODO: switch to official https://github.com/larry0x/cw-plus-plus once merged -cw-paginate-storage = { version = "^2.4", git = "https://github.com/DA0-DA0/dao-contracts.git" } +# TODO: switch to official https://github.com/larry0x/cw-plus-plus +# requires merge of https://github.com/larry0x/cw-plus-plus/pull/25 +cw-ownable = { git = "https://github.com/mintthemoon/cw-plus-plus", revision = "eb4445e07cd0da2859c7313de569b83a773cc407", package = "cw-ownable" } cw-storage-plus = "^2.0" cw-utils = "^2.0" schemars = "^0.8" diff --git a/packages/cw721/Cargo.toml b/packages/cw721/Cargo.toml index 58b2f05da..fb873160e 100644 --- a/packages/cw721/Cargo.toml +++ b/packages/cw721/Cargo.toml @@ -19,7 +19,6 @@ doctest = false # disable doc tests cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-ownable = { workspace = true } -cw-paginate-storage = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw2 = { workspace = true } From 6e3f86ff034ea22bc0c7b2ccff235e3d92760a69 Mon Sep 17 00:00:00 2001 From: mintthemoon Date: Tue, 13 Aug 2024 16:59:45 -0400 Subject: [PATCH 3/3] updates to cw-ownable --- Cargo.lock | 18 +++--- Cargo.toml | 2 +- packages/cw721/src/execute.rs | 45 ++++++++------- packages/cw721/src/msg.rs | 60 +++++++++++++------- packages/cw721/src/query.rs | 7 +-- packages/cw721/src/state.rs | 3 +- packages/cw721/src/testing/contract_tests.rs | 10 ++-- packages/cw721/src/testing/unit_tests.rs | 15 +++-- packages/cw721/src/traits.rs | 16 +++--- 9 files changed, 96 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78a45efbf..8a81b79cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,9 +411,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -517,7 +517,7 @@ dependencies = [ [[package]] name = "cw-address-like" version = "2.0.4" -source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" +source = "git+https://github.com/mintthemoon/cw-plus-plus?branch=dev#c30245f779a87732b29150d43e51ddd2d8997725" dependencies = [ "cosmwasm-std 2.1.3", ] @@ -560,7 +560,7 @@ dependencies = [ [[package]] name = "cw-ownable" version = "0.6.0" -source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" +source = "git+https://github.com/mintthemoon/cw-plus-plus?branch=dev#c30245f779a87732b29150d43e51ddd2d8997725" dependencies = [ "cosmwasm-schema 2.1.3", "cosmwasm-std 2.1.3", @@ -585,7 +585,7 @@ dependencies = [ [[package]] name = "cw-ownable-derive" version = "0.6.0" -source = "git+https://github.com/mintthemoon/cw-plus-plus#eb4445e07cd0da2859c7313de569b83a773cc407" +source = "git+https://github.com/mintthemoon/cw-plus-plus?branch=dev#c30245f779a87732b29150d43e51ddd2d8997725" dependencies = [ "proc-macro2", "quote", @@ -1649,9 +1649,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.206" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" dependencies = [ "serde_derive", ] @@ -1676,9 +1676,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.206" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 99f18abbd..aa00e48e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ cw721-base-018 = { git = "https://github.com/CosmWasm/cw-nfts", tag = "v0.18.0" cw-multi-test = { version = "^2.1", features = ["cosmwasm_2_0"] } # TODO: switch to official https://github.com/larry0x/cw-plus-plus # requires merge of https://github.com/larry0x/cw-plus-plus/pull/25 -cw-ownable = { git = "https://github.com/mintthemoon/cw-plus-plus", revision = "eb4445e07cd0da2859c7313de569b83a773cc407", package = "cw-ownable" } +cw-ownable = { git = "https://github.com/mintthemoon/cw-plus-plus", branch = "dev", package = "cw-ownable" } cw-storage-plus = "^2.0" cw-utils = "^2.0" schemars = "^0.8" diff --git a/packages/cw721/src/execute.rs b/packages/cw721/src/execute.rs index a99f80295..1d5b5fc04 100644 --- a/packages/cw721/src/execute.rs +++ b/packages/cw721/src/execute.rs @@ -1,8 +1,11 @@ use cosmwasm_std::{ Addr, Api, BankMsg, Binary, Coin, CustomMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, - StdResult, Storage, + StdError, StdResult, Storage, +}; +use cw_ownable::{ + assert_owner, get_ownership, initialize_owner, update_ownership, Action, Ownership, + OwnershipError, }; -use cw_ownable::{none_or, Action, Ownership, OwnershipError}; use cw_storage_plus::Item; use cw_utils::Expiration; @@ -15,7 +18,7 @@ use crate::{ msg::{CollectionInfoMsg, Cw721InstantiateMsg, Cw721MigrateMsg, NftInfoMsg}, query::query_collection_info_and_extension, receiver::Cw721ReceiveMsg, - state::{CollectionInfo, Cw721Config, NftInfo, CREATOR, MINTER}, + state::{CollectionInfo, Cw721Config, NftInfo, MINTER}, traits::{ Cw721CustomMsg, Cw721Execute, Cw721State, FromAttributesState, StateFactory, ToAttributesState, @@ -104,7 +107,7 @@ pub fn initialize_creator( api: &dyn Api, creator: Option<&str>, ) -> StdResult> { - CREATOR.initialize_owner(storage, api, creator) + initialize_owner(storage, api, creator) } pub fn initialize_minter( @@ -390,26 +393,24 @@ where } pub fn update_minter_ownership( - api: &dyn Api, - storage: &mut dyn Storage, + deps: DepsMut, env: &Env, info: &MessageInfo, action: Action, ) -> Result, Cw721ContractError> { - let ownership = MINTER.update_ownership(api, storage, &env.block, &info.sender, action)?; + let ownership = MINTER.update_ownership(deps, &env.block, &info.sender, action)?; Ok(Response::new() .add_attribute("update_minter_ownership", info.sender.to_string()) .add_attributes(ownership.into_attributes())) } pub fn update_creator_ownership( - api: &dyn Api, - storage: &mut dyn Storage, + deps: DepsMut, env: &Env, info: &MessageInfo, action: Action, ) -> Result, Cw721ContractError> { - let ownership = CREATOR.update_ownership(api, storage, &env.block, &info.sender, action)?; + let ownership = update_ownership(deps, &env.block, &info.sender, action)?; Ok(Response::new() .add_attribute("update_creator_ownership", info.sender.to_string()) .add_attributes(ownership.into_attributes())) @@ -450,7 +451,7 @@ pub fn set_withdraw_address( sender: &Addr, address: String, ) -> Result, Cw721ContractError> { - CREATOR.assert_owner(deps.storage, sender)?; + assert_owner(deps.storage, sender)?; deps.api.addr_validate(&address)?; let config = Cw721Config::>::default(); config.withdraw_address.save(deps.storage, &address)?; @@ -463,7 +464,7 @@ pub fn remove_withdraw_address( storage: &mut dyn Storage, sender: &Addr, ) -> Result, Cw721ContractError> { - CREATOR.assert_owner(storage, sender)?; + assert_owner(storage, sender)?; let config = Cw721Config::>::default(); let address = config.withdraw_address.may_load(storage)?; match address { @@ -579,7 +580,7 @@ pub fn assert_minter(storage: &dyn Storage, sender: &Addr) -> Result<(), Cw721Co } pub fn assert_creator(storage: &dyn Storage, sender: &Addr) -> Result<(), Cw721ContractError> { - if CREATOR.assert_owner(storage, sender).is_err() { + if assert_owner(storage, sender).is_err() { return Err(Cw721ContractError::NotCreator {}); } Ok(()) @@ -630,7 +631,7 @@ pub fn migrate_creator( match msg { Cw721MigrateMsg::WithUpdate { creator, .. } => { if let Some(creator) = creator { - CREATOR.initialize_owner(storage, api, Some(creator.as_str()))?; + initialize_owner(storage, api, Some(creator.as_str()))?; return Ok(response.add_attribute("creator", creator)); } } @@ -677,10 +678,9 @@ pub fn migrate_legacy_minter_and_creator( return Ok(response); } // in v0.17/18 cw_ownable::OWNERSHIP was used for minter, now it is used for creator - let ownership_previously_used_as_minter = CREATOR.item.may_load(storage)?; - let creator_and_minter = match ownership_previously_used_as_minter { + let creator_and_minter = match get_ownership(storage) { // v0.17/18 ownership migration - Some(ownership) => { + Ok(ownership) => { // owner is used for both: creator and minter // since it is already set for creator, we only need to migrate minter let owner = ownership.owner.map(|a| a.to_string()); @@ -688,15 +688,20 @@ pub fn migrate_legacy_minter_and_creator( owner } // migration below v0.17 - None => { + Err(StdError::NotFound { .. }) => { let legacy_minter_store: Item = Item::new("minter"); let legacy_minter = legacy_minter_store.load(storage)?; MINTER.initialize_owner(storage, api, Some(legacy_minter.as_str()))?; - CREATOR.initialize_owner(storage, api, Some(legacy_minter.as_str()))?; + initialize_owner(storage, api, Some(legacy_minter.as_str()))?; Some(legacy_minter.to_string()) } + // store access failed + Err(e) => return Err(e.into()), }; - Ok(response.add_attribute("creator_and_minter", none_or(creator_and_minter.as_ref()))) + Ok(response.add_attribute( + "creator_and_minter", + creator_and_minter.unwrap_or("none".to_string()), + )) } /// Migrates only in case collection_info is not present diff --git a/packages/cw721/src/msg.rs b/packages/cw721/src/msg.rs index c7127b7c9..4c6cca785 100644 --- a/packages/cw721/src/msg.rs +++ b/packages/cw721/src/msg.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ to_json_binary, Addr, Binary, Coin, ContractInfoResponse, Decimal, Deps, Env, MessageInfo, Timestamp, }; -use cw_ownable::{Action, Ownership}; +use cw_ownable::{is_owner, Action, Ownership}; use cw_utils::Expiration; use serde::Serialize; use url::Url; @@ -15,8 +15,8 @@ use crate::execute::{assert_creator, assert_minter}; use crate::state::{ Attribute, CollectionExtension, CollectionExtensionAttributes, CollectionInfo, NftInfo, Trait, ATTRIBUTE_DESCRIPTION, ATTRIBUTE_EXPLICIT_CONTENT, ATTRIBUTE_EXTERNAL_LINK, ATTRIBUTE_IMAGE, - ATTRIBUTE_ROYALTY_INFO, ATTRIBUTE_START_TRADING_TIME, CREATOR, - MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_ROYALTY_SHARE_DELTA_PCT, MAX_ROYALTY_SHARE_PCT, MINTER, + ATTRIBUTE_ROYALTY_INFO, ATTRIBUTE_START_TRADING_TIME, MAX_COLLECTION_DESCRIPTION_LENGTH, + MAX_ROYALTY_SHARE_DELTA_PCT, MAX_ROYALTY_SHARE_PCT, MINTER, }; use crate::traits::{Cw721CustomMsg, Cw721State, FromAttributesState, ToAttributesState}; use crate::NftExtension; @@ -461,29 +461,41 @@ impl StateFactory> _current: Option<&CollectionExtension>, ) -> Result<(), Cw721ContractError> { let deps = deps.ok_or(Cw721ContractError::NoDeps)?; - let sender = info.map(|i| i.sender.clone()); + let sender = info.map(|i| &i.sender); // start trading time can only be updated by minter - let minter_initialized = MINTER.item.may_load(deps.storage)?; + let is_minter_or_uninitialized = match sender + .map(|addr| MINTER.is_owner(deps.storage, addr)) + .transpose() + { + // if Some(bool), bool represents the `is_owner` check result. + // if None, `info` was none and the check is skipped. + Ok(is_minter) => is_minter.unwrap_or(true), + // `is_owner` returns an error if the store is not initialized. + // the check is skipped in this case as well. + Err(_) => true, + }; if self.start_trading_time.is_some() - && minter_initialized.is_some() - && sender.is_some() - && MINTER - .assert_owner(deps.storage, &sender.clone().unwrap()) - .is_err() + && MINTER.item.exists(deps.storage) + && !is_minter_or_uninitialized { return Err(Cw721ContractError::NotMinter {}); } // all other props collection extension can only be updated by the creator - let creator_initialized = CREATOR.item.may_load(deps.storage)?; + let is_creator_or_uninitialized = + match sender.map(|addr| is_owner(deps.storage, addr)).transpose() { + // if Some(bool), bool represents the `is_owner` check result. + // if None, `info` was none and the check is skipped. + Ok(is_minter) => is_minter.unwrap_or(true), + // `is_owner` returns an error if the store is not initialized. + // the check is skipped in this case as well. + Err(_) => true, + }; if (self.description.is_some() || self.image.is_some() || self.external_link.is_some() || self.explicit_content.is_some()) && sender.is_some() - && creator_initialized.is_some() - && CREATOR - .assert_owner(deps.storage, &sender.unwrap()) - .is_err() + && !is_creator_or_uninitialized { return Err(Cw721ContractError::NotCreator {}); } @@ -683,14 +695,18 @@ where // collection metadata can only be updated by the creator. creator assertion is skipped for these cases: // - CREATOR store is empty/not initioized (like in instantiation) // - info is none (like in migration) - let creator_initialized = CREATOR.item.may_load(deps.storage)?; - if (self.name.is_some() || self.symbol.is_some()) - && creator_initialized.is_some() - && info.is_some() - && CREATOR - .assert_owner(deps.storage, &info.unwrap().sender) - .is_err() + let is_creator_or_uninitialized = match info + .map(|inf| is_owner(deps.storage, &inf.sender)) + .transpose() { + // if Some(bool), bool represents the `is_owner` check result. + // if None, `info` was none and the check is skipped. + Ok(is_minter) => is_minter.unwrap_or(true), + // `is_owner` returns an error if the store is not initialized. + // the check is skipped in this case as well. + Err(_) => true, + }; + if (self.name.is_some() || self.symbol.is_some()) && !is_creator_or_uninitialized { return Err(Cw721ContractError::NotCreator {}); } Ok(()) diff --git a/packages/cw721/src/query.rs b/packages/cw721/src/query.rs index 357c2bb7b..d393c6269 100644 --- a/packages/cw721/src/query.rs +++ b/packages/cw721/src/query.rs @@ -1,7 +1,7 @@ use cosmwasm_std::{ Addr, BlockInfo, CustomMsg, Deps, Empty, Env, Order, StdError, StdResult, Storage, }; -use cw_ownable::Ownership; +use cw_ownable::{get_ownership, Ownership}; use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Expiration}; @@ -16,8 +16,7 @@ use crate::{ OperatorResponse, OperatorsResponse, OwnerOfResponse, TokensResponse, }, state::{ - Approval, CollectionExtensionAttributes, CollectionInfo, Cw721Config, NftInfo, CREATOR, - MINTER, + Approval, CollectionExtensionAttributes, CollectionInfo, Cw721Config, NftInfo, MINTER, }, traits::{Contains, Cw721CustomMsg, Cw721Query, Cw721State, FromAttributesState}, DefaultOptionalCollectionExtension, DefaultOptionalNftExtension, @@ -71,7 +70,7 @@ pub fn query_minter_ownership(storage: &dyn Storage) -> StdResult StdResult> { - CREATOR.get_ownership(storage) + get_ownership(storage) } pub fn query_collection_info(storage: &dyn Storage) -> StdResult { diff --git a/packages/cw721/src/state.rs b/packages/cw721/src/state.rs index 43c37a8aa..4063e52c3 100644 --- a/packages/cw721/src/state.rs +++ b/packages/cw721/src/state.rs @@ -3,7 +3,7 @@ use cosmwasm_std::{ from_json, to_json_binary, Addr, Binary, BlockInfo, Decimal, Deps, Empty, Env, MessageInfo, StdResult, Storage, Timestamp, }; -use cw_ownable::{OwnershipStore, OWNERSHIP_KEY}; +use cw_ownable::OwnershipStore; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; use cw_utils::Expiration; use serde::de::DeserializeOwned; @@ -16,7 +16,6 @@ use crate::{traits::StateFactory, NftExtensionMsg}; /// !!! Important note here: !!! /// - creator is stored using using cw-ownable's OWNERSHIP singleton, so it is not stored here /// - in release v0.18.0 it was used for minter (which is confusing), but now it is used for creator -pub const CREATOR: OwnershipStore = OwnershipStore::new(OWNERSHIP_KEY); /// - minter is stored in the contract storage using cw_ownable::OwnershipStore (same as for OWNERSHIP but with different key) pub const MINTER: OwnershipStore = OwnershipStore::new("collection_minter"); diff --git a/packages/cw721/src/testing/contract_tests.rs b/packages/cw721/src/testing/contract_tests.rs index 5dacc4edc..0fe2f45a4 100644 --- a/packages/cw721/src/testing/contract_tests.rs +++ b/packages/cw721/src/testing/contract_tests.rs @@ -13,14 +13,14 @@ use crate::msg::{ }; use crate::msg::{CollectionInfoMsg, Cw721ExecuteMsg, Cw721InstantiateMsg, Cw721QueryMsg}; use crate::receiver::Cw721ReceiveMsg; -use crate::state::{NftExtension, Trait, CREATOR, MINTER}; +use crate::state::{NftExtension, Trait, MINTER}; use crate::{ traits::{Cw721Execute, Cw721Query}, Approval, DefaultOptionalCollectionExtensionMsg, DefaultOptionalNftExtension, DefaultOptionalNftExtensionMsg, Expiration, }; use crate::{CollectionExtension, CollectionInfoAndExtensionResponse, RoyaltyInfo}; -use cw_ownable::{Action, Ownership, OwnershipError}; +use cw_ownable::{get_ownership, Action, Ownership, OwnershipError}; const CONTRACT_NAME: &str = "Magic Power"; const SYMBOL: &str = "MGK"; @@ -113,7 +113,7 @@ fn test_instantiate() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(minter), minter_ownership.owner); - let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); + let creator_ownership = get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(creator.clone()), creator_ownership.owner); let collection_info = contract .query_collection_info_and_extension(deps.as_ref()) @@ -191,7 +191,7 @@ fn test_instantiate_with_collection_info_and_extension() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(minter), minter_ownership.owner); - let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); + let creator_ownership = get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(creator.clone()), creator_ownership.owner); let info = contract .query_collection_info_and_extension(deps.as_ref()) @@ -276,7 +276,7 @@ fn test_instantiate_with_minimal_collection_info_and_extension() { // it worked, let's query the state let minter_ownership = MINTER.get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(minter), minter_ownership.owner); - let creator_ownership = CREATOR.get_ownership(deps.as_ref().storage).unwrap(); + let creator_ownership = get_ownership(deps.as_ref().storage).unwrap(); assert_eq!(Some(creator), creator_ownership.owner); let info = contract .query_collection_info_and_extension(deps.as_ref()) diff --git a/packages/cw721/src/testing/unit_tests.rs b/packages/cw721/src/testing/unit_tests.rs index d1718c4af..3ae149bc5 100644 --- a/packages/cw721/src/testing/unit_tests.rs +++ b/packages/cw721/src/testing/unit_tests.rs @@ -6,7 +6,7 @@ use crate::{ NftExtensionMsg, RoyaltyInfoResponse, }, state::{ - NftExtension, Trait, CREATOR, MAX_COLLECTION_DESCRIPTION_LENGTH, + NftExtension, Trait, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_ROYALTY_SHARE_DELTA_PCT, MAX_ROYALTY_SHARE_PCT, MINTER, }, traits::{Cw721Execute, Cw721Query}, @@ -17,7 +17,7 @@ use cosmwasm_std::{ Addr, Api, Decimal, Timestamp, }; use cw2::ContractVersion; -use cw_ownable::Action; +use cw_ownable::{get_ownership, Action}; use unit_tests::contract_tests::MockAddrFactory; use unit_tests::multi_tests::{CREATOR_ADDR, MINTER_ADDR, OTHER_ADDR}; @@ -93,8 +93,7 @@ fn test_instantiation() { .map(|a| a.into_string()); assert_eq!(minter, Some("minter".to_string())); - let creator = CREATOR - .get_ownership(deps.as_ref().storage) + let creator = get_ownership(deps.as_ref().storage) .unwrap() .owner .map(|a| a.into_string()); @@ -138,7 +137,7 @@ fn test_instantiation_with_proper_minter_and_creator() { let minter = MINTER.item.load(deps.as_ref().storage).unwrap().owner; assert_eq!(minter, Some(info_minter_and_creator.sender.clone())); - let creator = CREATOR.item.load(deps.as_ref().storage).unwrap().owner; + let creator = get_ownership(deps.as_ref().storage).unwrap().owner; assert_eq!(creator, Some(info_minter_and_creator.sender)); } // case 2: minter and creator are set @@ -166,7 +165,7 @@ fn test_instantiation_with_proper_minter_and_creator() { let minter = MINTER.item.load(deps.as_ref().storage).unwrap().owner; assert_eq!(minter, Some(Addr::unchecked(MINTER_ADDR.to_string()))); - let creator = CREATOR.item.load(deps.as_ref().storage).unwrap().owner; + let creator = get_ownership(deps.as_ref().storage).unwrap().owner; assert_eq!(creator, Some(Addr::unchecked(CREATOR_ADDR.to_string()))); } // case 3: sender is minter and creator is set @@ -194,7 +193,7 @@ fn test_instantiation_with_proper_minter_and_creator() { let minter = MINTER.item.load(deps.as_ref().storage).unwrap().owner; assert_eq!(minter, Some(info.sender)); - let creator = CREATOR.item.load(deps.as_ref().storage).unwrap().owner; + let creator = get_ownership(deps.as_ref().storage).unwrap().owner; assert_eq!(creator, Some(Addr::unchecked(CREATOR_ADDR.to_string()))); } // case 4: sender is creator and minter is set @@ -222,7 +221,7 @@ fn test_instantiation_with_proper_minter_and_creator() { let minter = MINTER.item.load(deps.as_ref().storage).unwrap().owner; assert_eq!(minter, Some(Addr::unchecked(MINTER_ADDR.to_string()))); - let creator = CREATOR.item.load(deps.as_ref().storage).unwrap().owner; + let creator = get_ownership(deps.as_ref().storage).unwrap().owner; assert_eq!(creator, Some(info.sender)); } } diff --git a/packages/cw721/src/traits.rs b/packages/cw721/src/traits.rs index 83de4764d..c2076f117 100644 --- a/packages/cw721/src/traits.rs +++ b/packages/cw721/src/traits.rs @@ -220,13 +220,13 @@ pub trait Cw721Execute< Cw721ExecuteMsg::Burn { token_id } => self.burn_nft(deps, env, info, token_id), #[allow(deprecated)] Cw721ExecuteMsg::UpdateOwnership(action) => { - self.update_minter_ownership(deps.api, deps.storage, env, info, action) + self.update_minter_ownership(deps, env, info, action) } Cw721ExecuteMsg::UpdateMinterOwnership(action) => { - self.update_minter_ownership(deps.api, deps.storage, env, info, action) + self.update_minter_ownership(deps, env, info, action) } Cw721ExecuteMsg::UpdateCreatorOwnership(action) => { - self.update_creator_ownership(deps.api, deps.storage, env, info, action) + self.update_creator_ownership(deps, env, info, action) } #[allow(deprecated)] Cw721ExecuteMsg::UpdateExtension { msg } => { @@ -391,24 +391,22 @@ pub trait Cw721Execute< fn update_minter_ownership( &self, - api: &dyn Api, - storage: &mut dyn Storage, + deps: DepsMut, env: &Env, info: &MessageInfo, action: Action, ) -> Result, Cw721ContractError> { - update_minter_ownership::(api, storage, env, info, action) + update_minter_ownership::(deps, env, info, action) } fn update_creator_ownership( &self, - api: &dyn Api, - storage: &mut dyn Storage, + deps: DepsMut, env: &Env, info: &MessageInfo, action: Action, ) -> Result, Cw721ContractError> { - update_creator_ownership::(api, storage, env, info, action) + update_creator_ownership::(deps, env, info, action) } /// Custom msg execution. This is a no-op in default implementation.