From 934eb6a927458ff606a69950b66ba8329f37333a Mon Sep 17 00:00:00 2001 From: FengFeng <1290017556@qq.com> Date: Sun, 14 Jul 2024 05:59:14 +0800 Subject: [PATCH] change admin func and add more test case --- .gitignore | 1 + Cargo.lock | 444 +++++++++++++++++++++++++++-------------- Cargo.toml | 3 +- src/contract.rs | 362 +++++++++++++++++++++------------ src/lib.rs | 4 +- src/multitest/mod.rs | 23 +++ src/multitest/tests.rs | 161 +++++++++++++++ src/responses.rs | 6 - 8 files changed, 724 insertions(+), 280 deletions(-) create mode 100644 src/multitest/mod.rs create mode 100644 src/multitest/tests.rs delete mode 100644 src/responses.rs diff --git a/.gitignore b/.gitignore index b8b735b..d16a8d0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ target # Cargo.lock package-lock.json artifacts +yarn.lock diff --git a/Cargo.lock b/Cargo.lock index ab3eb67..be44d9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "appchain-grant-vota" @@ -36,6 +36,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -44,9 +50,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -80,9 +86,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "byteorder" @@ -92,9 +98,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cfg-if" @@ -104,9 +110,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_panic" @@ -125,32 +131,32 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.0" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" +checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" dependencies = [ "digest 0.10.7", - "ecdsa", + "ecdsa 0.16.9", "ed25519-zebra", - "k256", + "k256 0.13.1", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.5.0" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" +checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.4.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef683a9c1c4eabd6d31515719d0d2cc66952c4c87f7eb192bfc90384517dc34" +checksum = "7879036156092ad1c22fe0d7316efc5a5eceec2bc3906462a2560215f2a2f929" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -161,9 +167,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.4.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9567025acbb4c0c008178393eb53b3ac3c2e492c25949d3bf415b9cbe80772d8" +checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" dependencies = [ "proc-macro2", "quote", @@ -172,9 +178,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.0" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d6864742e3a7662d024b51a94ea81c9af21db6faea2f9a6d2232bb97c6e53e" +checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" dependencies = [ "base64", "bech32", @@ -194,9 +200,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1c574d30feffe4b8121e61e839c231a5ce21901221d2fb4d5c945968a4f00" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -204,18 +210,30 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -248,9 +266,9 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.18.0" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e2c2f2c0877b839c5cad85e67811074e854a50c1ff3085eb8290b1c27809c" +checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" dependencies = [ "anyhow", "cosmwasm-std", @@ -258,18 +276,18 @@ dependencies = [ "cw-utils", "derivative", "itertools", + "k256 0.11.6", "prost", "schemars", "serde", - "sha2 0.10.8", "thiserror", ] [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -278,9 +296,9 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9f351a4e4d81ef7c890e44d903f8c0bdcdc00f094fd3a181eaf70c0eec7a3a" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -293,23 +311,34 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9431d14f64f49e41c6ef5561ed11a5391c417d0cb16455dea8cdcb9037a8d197" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "der" -version = "0.7.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -349,22 +378,34 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -384,25 +425,45 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", "digest 0.10.7", - "ff", + "ff 0.12.1", "generic-array", - "group", - "pkcs8", + "group 0.12.1", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle", "zeroize", ] @@ -413,6 +474,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.0" @@ -442,22 +513,33 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -473,9 +555,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hex" @@ -494,28 +576,40 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.5", ] [[package]] name = "itertools" -version = "0.11.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "k256" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] [[package]] name = "k256" @@ -524,18 +618,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", - "signature", + "signature 2.2.0", ] [[package]] name = "konst" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030400e39b2dff8beaa55986a17e0014ad657f569ca92426aafcb5e8e71faee7" +checksum = "50a0ba6de5f7af397afff922f22c149ff605c766cd3269cf6c1cd5e466dbe3b9" dependencies = [ "const_panic", "konst_kernel", @@ -545,9 +639,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3376133edc39f027d551eb77b077c2865a0ef252b2e7d0dd6b6dc303db95d8b5" +checksum = "be0a455a1719220fd6adf756088e1c69a85bf14b6a9e24537a5cc04f503edb2b" dependencies = [ "typewit", ] @@ -560,27 +654,37 @@ checksum = "4e28ab1dc35e09d60c2b8c90d12a9a8d9666c876c10a3739a3196db0103b6043" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "pkcs8" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] [[package]] name = "pkcs8" @@ -588,8 +692,8 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.9", + "spki 0.7.3", ] [[package]] @@ -628,18 +732,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ "bytes", "prost-derive", @@ -647,22 +751,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" +checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 2.0.38", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -682,6 +786,17 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -694,15 +809,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "schemars_derive", @@ -712,14 +827,28 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.71", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", ] [[package]] @@ -728,25 +857,25 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.9", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -762,40 +891,40 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.71", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.71", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -828,22 +957,42 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.9", ] [[package]] @@ -854,9 +1003,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 = "sylvia" @@ -864,8 +1013,11 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f33388920659b494dab887f3bb40ebb071c602750597575034bea7c63ab12800" dependencies = [ + "anyhow", "cosmwasm-schema", "cosmwasm-std", + "cw-multi-test", + "derivative", "konst", "schemars", "serde", @@ -901,9 +1053,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -912,29 +1064,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.71", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" @@ -955,9 +1107,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6779a69cc5f9a7388274a0a8a353eb1c9e45195f9ae74a26690b055a7cf9592a" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" dependencies = [ "typewit_proc_macros", ] @@ -976,9 +1128,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "version_check" @@ -994,15 +1146,15 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winnow" -version = "0.5.17" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index a2a617a..98c3f2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,4 +57,5 @@ sylvia = "0.8.1" thiserror = "1.0.44" [dev-dependencies] -cw-multi-test = "0.18.0" +cw-multi-test = "0.16.2" +sylvia = {version = "0.8.1", features = ["mt"] } diff --git a/src/contract.rs b/src/contract.rs index 76d27b1..c2082bf 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -3,10 +3,12 @@ //! Version: 0.1.0 //! License: Apache-2.0 +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - coins, Addr, BankMsg, Deps, DepsMut, Empty, Env, Event, MessageInfo, Order, Response, StdError, - StdResult, Uint128, + coins, Addr, BankMsg, Deps, DepsMut, Env, Event, MessageInfo, Response, StdError, StdResult, + Uint128, }; + use cw_storage_plus::{Item, Map}; use std::collections::HashMap; use sylvia::contract; @@ -14,14 +16,33 @@ use sylvia::contract; #[cfg(not(feature = "library"))] use sylvia::entry_points; -use crate::{error::ContractError, responses::AdminListResp}; +use crate::error::ContractError; + +#[cw_serde] +pub struct Admin { + pub admin: Addr, +} + +impl Admin { + pub fn is_admin(&self, addr: impl AsRef) -> bool { + let addr = addr.as_ref(); + self.admin.as_ref() == addr + } +} + +#[cw_serde] +pub struct InstantiateMsgData { + pub admin: Addr, + pub operator: Addr, + pub beneficiary: Addr, +} pub struct AGContract<'a> { - pub(crate) admins: Map<'a, &'a Addr, Empty>, + pub(crate) admin: Item<'a, Admin>, + pub(crate) operator: Item<'a, Addr>, pub(crate) beneficiary: Item<'a, Addr>, - pub(crate) round_id: Item<'a, u64>, - pub(crate) projects: Map<'a, (&'a str, &'a str), HashMap>, // (round_id, project_id) -> {'arch':100, 'atom':20} - pub(crate) voters: Map<'a, (&'a str, &'a str, &'a Addr), HashMap>, // (round_id, project_id, voter) -> {'arch':100, 'atom':20} + pub(crate) projects: Map<'a, &'a str, HashMap>, // project_id -> {'arch':100, 'atom':20} + pub(crate) voters: Map<'a, (&'a str, &'a Addr), HashMap>, // (project_id, voter) -> {'arch':100, 'atom':20} } #[cfg_attr(not(feature = "library"), entry_points)] @@ -30,9 +51,9 @@ pub struct AGContract<'a> { impl AGContract<'_> { pub const fn new() -> Self { Self { - admins: Map::new("admins"), + admin: Item::new("admin"), + operator: Item::new("operator"), beneficiary: Item::new("beneficiary"), - round_id: Item::new("round"), projects: Map::new("projects"), voters: Map::new("votes"), } @@ -42,51 +63,55 @@ impl AGContract<'_> { pub fn instantiate( &self, ctx: (DepsMut, Env, MessageInfo), - admins: Vec, + data: InstantiateMsgData, ) -> Result { - let (deps, _, info) = ctx; - - for admin in admins { - let admin = deps.api.addr_validate(&admin)?; - self.admins.save(deps.storage, &admin, &Empty {})?; - } - self.round_id.save(deps.storage, &1)?; - self.beneficiary.save(deps.storage, &info.sender)?; + let (deps, _, _) = ctx; + let InstantiateMsgData { + admin, + operator, + beneficiary, + } = data; + let admin = Admin { admin }; + self.admin.save(deps.storage, &admin)?; + self.operator.save(deps.storage, &operator)?; + self.beneficiary.save(deps.storage, &beneficiary)?; Ok(Response::new()) } // ============= Query ============= // #[msg(query)] - pub fn admin_list(&self, ctx: (Deps, Env)) -> StdResult { + pub fn admin(&self, ctx: (Deps, Env)) -> StdResult { let (deps, _) = ctx; - let admins: Result<_, _> = self - .admins - .keys(deps.storage, None, None, Order::Ascending) - .map(|addr| addr.map(String::from)) - .collect(); + let admin = self.admin.load(deps.storage)?; - Ok(AdminListResp { admins: admins? }) + Ok(admin) } #[msg(query)] - pub fn round_id(&self, ctx: (Deps, Env)) -> StdResult { + pub fn operator(&self, ctx: (Deps, Env)) -> StdResult { let (deps, _) = ctx; - let round_id = self.round_id.may_load(deps.storage)?; - match round_id { - Some(round_id) => Ok(round_id), - None => Err(StdError::generic_err("Round not found")), - } + let operator = self.operator.load(deps.storage)?; + + Ok(operator) + } + + #[msg(query)] + pub fn beneficiary(&self, ctx: (Deps, Env)) -> StdResult { + let (deps, _) = ctx; + + let beneficiary = self.beneficiary.load(deps.storage)?; + + Ok(beneficiary) } #[msg(query)] - pub fn project(&self, ctx: (Deps, Env), project_id: u64, round_id: u64) -> StdResult> { + pub fn project(&self, ctx: (Deps, Env), project_id: u64) -> StdResult> { let (deps, _) = ctx; - let project = self.projects.may_load( - deps.storage, - (&round_id.to_string(), &project_id.to_string()), - )?; + let project = self + .projects + .may_load(deps.storage, &project_id.to_string())?; match project { Some(project) => Ok(project), @@ -98,16 +123,14 @@ impl AGContract<'_> { pub fn project_voter( &self, ctx: (Deps, Env), - round_id: u64, project_id: u64, voter: String, ) -> StdResult> { let (deps, _) = ctx; let voter_addr = deps.api.addr_validate(&voter)?; - let voter = self.voters.may_load( - deps.storage, - (&round_id.to_string(), &project_id.to_string(), &voter_addr), - )?; + let voter = self + .voters + .may_load(deps.storage, (&project_id.to_string(), &voter_addr))?; match voter { Some(voter) => Ok(voter), @@ -115,31 +138,45 @@ impl AGContract<'_> { } } + // Only admin can execute + fn is_admin(&self, deps: Deps, sender: &str) -> StdResult { + let admin = self.admin.load(deps.storage)?; + let can = admin.is_admin(&sender); + Ok(can) + } + + // Only operator/admin can execute + fn is_operator(&self, deps: Deps, sender: &str) -> StdResult { + let admin = self.admin.load(deps.storage)?; + let can_admin = admin.is_admin(&sender); + + let operator = self.operator.load(deps.storage)?; + let can_operator = sender.to_string() == operator.to_string(); + + let can = can_admin || can_operator; + Ok(can) + } + // ============= Execute ============= // #[msg(exec)] - pub fn add_member( + pub fn change_operator( &self, ctx: (DepsMut, Env, MessageInfo), - admin: String, + address: Addr, ) -> Result { let (deps, _, info) = ctx; - if !self.admins.has(deps.storage, &info.sender) { + + if !self.is_admin(deps.as_ref(), info.sender.as_ref())? { return Err(ContractError::Unauthorized { sender: info.sender, }); } - let admin = deps.api.addr_validate(&admin)?; - if self.admins.has(deps.storage, &admin) { - return Err(ContractError::NoDupAddress { address: admin }); - } - - self.admins.save(deps.storage, &admin, &Empty {})?; + self.operator.save(deps.storage, &address)?; - let resp = Response::new() - .add_attribute("action", "add_member") - .add_event(Event::new("admin_added").add_attribute("addr", admin)); - Ok(resp) + Ok(Response::new() + .add_attribute("action", "change_operator") + .add_attribute("address", address.to_string())) } #[msg(exec)] @@ -149,7 +186,8 @@ impl AGContract<'_> { address: String, ) -> Result { let (deps, _, info) = ctx; - if !self.admins.has(deps.storage, &info.sender) { + + if !self.is_operator(deps.as_ref(), info.sender.as_ref())? { return Err(ContractError::Unauthorized { sender: info.sender, }); @@ -176,7 +214,6 @@ impl AGContract<'_> { let coin = cw_utils::one_coin(&info)?; let denom = coin.denom; - let round_id = self.round_id.load(deps.storage)?; let mut total_amounts: u128 = 0; for (project_id, vote) in project_ids.iter().zip(amounts.iter()) { @@ -184,10 +221,10 @@ impl AGContract<'_> { total_amounts += amount; // Update round project - let mut project = match self.projects.may_load( - deps.storage, - (&round_id.to_string(), &project_id.to_string()), - )? { + let mut project = match self + .projects + .may_load(deps.storage, &project_id.to_string())? + { Some(project) => project, None => HashMap::new(), }; @@ -199,17 +236,14 @@ impl AGContract<'_> { project.insert(denom.clone(), amount); } - self.projects.save( - deps.storage, - (&round_id.to_string(), &project_id.to_string()), - &project, - )?; + self.projects + .save(deps.storage, &project_id.to_string(), &project)?; // Update round project voter - let mut voter = match self.voters.may_load( - deps.storage, - (&round_id.to_string(), &project_id.to_string(), &info.sender), - )? { + let mut voter = match self + .voters + .may_load(deps.storage, (&project_id.to_string(), &info.sender))? + { Some(voter) => voter, None => HashMap::new(), }; @@ -223,7 +257,7 @@ impl AGContract<'_> { self.voters.save( deps.storage, - (&round_id.to_string(), &project_id.to_string(), &info.sender), + (&project_id.to_string(), &info.sender), &voter, )?; } @@ -248,7 +282,6 @@ impl AGContract<'_> { .add_event( Event::new("batch_vote") .add_attribute("sender", info.sender) - .add_attribute("round_id", round_id.to_string()) .add_attribute( "projects", format!( @@ -275,24 +308,6 @@ impl AGContract<'_> { ); Ok(resp) } - - #[msg(exec)] - pub fn end_round(&self, ctx: (DepsMut, Env, MessageInfo)) -> Result { - let (deps, _, info) = ctx; - if !self.admins.has(deps.storage, &info.sender) { - return Err(ContractError::Unauthorized { - sender: info.sender, - }); - } - - let round_id = self.round_id.load(deps.storage)?; - self.round_id.save(deps.storage, &(round_id + 1))?; - - let resp = Response::new() - .add_attribute("action", "end_round") - .add_event(Event::new("end_round").add_attribute("round_id", round_id.to_string())); - Ok(resp) - } } #[cfg(test)] @@ -304,7 +319,7 @@ mod tests { use super::*; #[test] - fn admin_list_query() { + fn admin_operator_beneficiary_query() { let mut deps = mock_dependencies(); let env = mock_env(); @@ -313,24 +328,56 @@ mod tests { env.clone(), mock_info("sender", &[]), InstantiateMsg { - admins: vec!["admin1".to_owned(), "admin2".to_owned()], + data: InstantiateMsgData { + admin: Addr::unchecked("admin"), + operator: Addr::unchecked("operator"), + beneficiary: Addr::unchecked("beneficiary"), + }, }, ) .unwrap(); - let msg = QueryMsg::AdminList {}; - let resp = query(deps.as_ref(), env, ContractQueryMsg::AGContract(msg)).unwrap(); - let resp: AdminListResp = from_json(&resp).unwrap(); + let admin_addr: Admin = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Admin {}), + ) + .unwrap(), + ) + .unwrap(); assert_eq!( - resp, - AdminListResp { - admins: vec!["admin1".to_owned(), "admin2".to_owned()], + admin_addr, + Admin { + admin: Addr::unchecked("admin") } ); + + let operator_addr: Addr = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Operator {}), + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(operator_addr, Addr::unchecked("operator")); + + let beneficiary_addr: Addr = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Beneficiary {}), + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(beneficiary_addr, Addr::unchecked("beneficiary")); } #[test] - fn add_member() { + fn change_operator() { let mut deps = mock_dependencies(); let env = mock_env(); @@ -339,35 +386,105 @@ mod tests { env.clone(), mock_info("sender", &[]), InstantiateMsg { - admins: vec!["admin1".to_owned(), "admin2".to_owned()], + data: InstantiateMsgData { + admin: Addr::unchecked("admin"), + operator: Addr::unchecked("operator"), + beneficiary: Addr::unchecked("beneficiary"), + }, }, ) .unwrap(); - let info = mock_info("admin1", &[]); - let msg = ExecMsg::AddMember { - admin: "admin3".to_owned(), + let admin_info = mock_info("admin", &[]); + let msg = ExecMsg::ChangeOperator { + address: Addr::unchecked("operator_changed"), }; execute( deps.as_mut(), env.clone(), - info, + admin_info.clone(), ContractExecMsg::AGContract(msg), ) .unwrap(); - let msg = QueryMsg::AdminList {}; - let resp = query(deps.as_ref(), env, ContractQueryMsg::AGContract(msg)).unwrap(); - let resp: AdminListResp = from_json(&resp).unwrap(); + let operator_changed_addr: Addr = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Operator {}), + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(operator_changed_addr, Addr::unchecked("operator_changed")); + + let no_access_info = mock_info("admin1", &[]); + let no_access_change_operator_error = execute( + deps.as_mut(), + env.clone(), + no_access_info.clone(), + ContractExecMsg::AGContract(ExecMsg::ChangeOperator { + address: Addr::unchecked("operator_changed"), + }), + ) + .unwrap_err(); + assert_eq!( - resp, - AdminListResp { - admins: vec![ - "admin1".to_owned(), - "admin2".to_owned(), - "admin3".to_owned() - ], - } + no_access_change_operator_error, + ContractError::Unauthorized { + sender: no_access_info.clone().sender + }, + ); + let no_access_set_beneficiary_error = execute( + deps.as_mut(), + env.clone(), + no_access_info.clone(), + ContractExecMsg::AGContract(ExecMsg::SetBeneficiary { + address: "0x1a4B7626f3627EECf64b7beFFE599625080b28aA".to_string(), + }), + ) + .unwrap_err(); + + assert_eq!( + no_access_set_beneficiary_error, + ContractError::Unauthorized { + sender: no_access_info.clone().sender + }, + ); + + let inited_beneficiary_addr: Addr = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Beneficiary {}), + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(inited_beneficiary_addr, Addr::unchecked("beneficiary")); + + execute( + deps.as_mut(), + env.clone(), + admin_info.clone(), + ContractExecMsg::AGContract(ExecMsg::SetBeneficiary { + address: "dora1xuentny2lw3zx5rheevpudut0we3ghf3d4dm5p".to_string(), + }), + ) + .unwrap(); + + let set_beneficiary_addr: Addr = from_json( + &query( + deps.as_ref(), + env.clone(), + ContractQueryMsg::AGContract(QueryMsg::Beneficiary {}), + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + set_beneficiary_addr, + Addr::unchecked("dora1xuentny2lw3zx5rheevpudut0we3ghf3d4dm5p") ); } @@ -382,7 +499,11 @@ mod tests { env.clone(), mock_info("sender", &[]), InstantiateMsg { - admins: vec!["admin1".to_owned(), "admin2".to_owned()], + data: InstantiateMsgData { + admin: Addr::unchecked("admin"), + operator: Addr::unchecked("operator"), + beneficiary: Addr::unchecked("beneficiary"), + }, }, ) .unwrap(); @@ -444,16 +565,5 @@ mod tests { ContractExecMsg::AGContract(msg), ) .unwrap(); - - // End round - let info = mock_info("admin1", &[]); - let msg = ExecMsg::EndRound {}; - execute( - deps.as_mut(), - env.clone(), - info, - ContractExecMsg::AGContract(msg), - ) - .unwrap(); } } diff --git a/src/lib.rs b/src/lib.rs index 5b7425d..a18a72d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ pub mod contract; pub mod error; -pub mod responses; + +#[cfg(test)] +mod multitest; diff --git a/src/multitest/mod.rs b/src/multitest/mod.rs new file mode 100644 index 0000000..a031ef0 --- /dev/null +++ b/src/multitest/mod.rs @@ -0,0 +1,23 @@ +mod tests; +use cosmwasm_std::Addr; +pub const DORA_DEMON: &str = "peaka"; + +pub fn user1() -> Addr { + Addr::unchecked("dora19lpkv3pt568wxmeuqewq4kr4qsfjax2vs4rxt4") +} + +pub fn user2() -> Addr { + Addr::unchecked("dora1aj0s6d0lhuyaztm8zrh69p73eh08zvqnh5kz6y") +} + +pub fn admin() -> Addr { + Addr::unchecked("dora1t58t7azqzq26406uwehgnfekal5kzym3m9lz4k") +} + +pub fn operator() -> Addr { + Addr::unchecked("dora1qdagdkg9me4253h9qyvx83sd4gpta6rzh2fa0j") +} + +pub fn beneficiary() -> Addr { + Addr::unchecked("dora1tuu2qpj0ytj2k7fta7u5fwruzeyyfqj5q4vq23") +} diff --git a/src/multitest/tests.rs b/src/multitest/tests.rs new file mode 100644 index 0000000..6841745 --- /dev/null +++ b/src/multitest/tests.rs @@ -0,0 +1,161 @@ +use std::collections::HashMap; + +use crate::contract::multitest_utils::CodeId; +use crate::contract::InstantiateMsgData; +use crate::multitest::*; +use cosmwasm_std::{coin, coins, Coin, Uint128}; +use cw_multi_test; +use sylvia::multitest::App; + +#[test] +fn mintable() { + let user_coin_amount = 410000; // 160000 + 90000 +160000 + + let baseapp = cw_multi_test::App::new(|router, _api, storage| { + router + .bank + .init_balance(storage, &user1(), coins(user_coin_amount, DORA_DEMON)) + .unwrap(); + router + .bank + .init_balance(storage, &user2(), coins(user_coin_amount, DORA_DEMON)) + .unwrap(); + }); + + let app = App::new(baseapp); + + let code_id = CodeId::store_code(&app); + + let contract = code_id + .instantiate(InstantiateMsgData { + admin: admin(), + operator: operator(), + beneficiary: beneficiary(), + }) + .with_label("AEZ contract") + .call(&user1().to_string()) + .unwrap(); + + let user1_balance = app + .app() + .wrap() + .query_balance(user1().to_string(), DORA_DEMON) + .unwrap(); + + assert_eq!( + user1_balance, + Coin { + amount: Uint128::from(user_coin_amount), + denom: DORA_DEMON.to_string() + } + ); + // User1 Vote 160000u128 + contract + .batch_vote(vec![1], vec![Uint128::from(160000u128)]) + .with_funds(&[coin(160000u128, DORA_DEMON)]) + .call(&user1().to_string()) + .unwrap(); + + // User1 Vote 90000u128 + contract + .batch_vote(vec![1], vec![Uint128::from(90000u128)]) + .with_funds(&[coin(90000u128, DORA_DEMON)]) + .call(&user1().to_string()) + .unwrap(); + + // User1 Vote 160000u128 + contract + .batch_vote(vec![1], vec![Uint128::from(160000u128)]) + .with_funds(&[coin(160000u128, DORA_DEMON)]) + .call(&user1().to_string()) + .unwrap(); + + let user1_balance_after_vote = app + .app() + .wrap() + .query_balance(user1().to_string(), DORA_DEMON) + .unwrap(); + + assert_eq!( + user1_balance_after_vote, + Coin { + amount: Uint128::from(0u128), + denom: DORA_DEMON.to_string() + } + ); + + // User2 Vote 100000u128 + contract + .batch_vote(vec![2], vec![Uint128::from(100000u128)]) + .with_funds(&[coin(100000u128, DORA_DEMON)]) + .call(&user2().to_string()) + .unwrap(); + + // User2 Vote 200000u128 + contract + .batch_vote(vec![1], vec![Uint128::from(200000u128)]) + .with_funds(&[coin(200000u128, DORA_DEMON)]) + .call(&user2().to_string()) + .unwrap(); + + let user2_balance_after_vote = app + .app() + .wrap() + .query_balance(user2().to_string(), DORA_DEMON) + .unwrap(); + + assert_eq!( + user2_balance_after_vote, + Coin { + amount: Uint128::from(user_coin_amount - 100000u128 - 200000u128), + denom: DORA_DEMON.to_string() + } + ); + + let beneficiary_balance_after_vote = app + .app() + .wrap() + .query_balance(beneficiary().to_string(), DORA_DEMON) + .unwrap(); + + assert_eq!( + beneficiary_balance_after_vote, + Coin { + amount: Uint128::from(160000u128 + 90000u128 + 160000u128 + 100000u128 + 200000u128), + denom: DORA_DEMON.to_string() + } + ); + + let project1_info = contract.project(1u64).unwrap(); + assert_eq!( + project1_info, + HashMap::from([( + DORA_DEMON.to_string(), + 160000u128 + 90000u128 + 160000u128 + 200000u128 + )]) + ); + + let project2_info = contract.project(2u64).unwrap(); + assert_eq!( + project2_info, + HashMap::from([(DORA_DEMON.to_string(), 100000u128)]) + ); + + let user1_vote_project1_info = contract.project_voter(1u64, user1().to_string()).unwrap(); + assert_eq!( + user1_vote_project1_info, + HashMap::from([(DORA_DEMON.to_string(), 160000u128 + 90000u128 + 160000u128)]) + ); + + let user2_vote_project2_info = contract.project_voter(2u64, user2().to_string()).unwrap(); + assert_eq!( + user2_vote_project2_info, + HashMap::from([(DORA_DEMON.to_string(), 100000u128)]) + ); + + let user2_vote_project1_info = contract.project_voter(1u64, user2().to_string()).unwrap(); + assert_eq!( + user2_vote_project1_info, + HashMap::from([(DORA_DEMON.to_string(), 200000u128)]) + ); +} diff --git a/src/responses.rs b/src/responses.rs deleted file mode 100644 index 9748395..0000000 --- a/src/responses.rs +++ /dev/null @@ -1,6 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, schemars::JsonSchema, Debug, Default)] -pub struct AdminListResp { - pub admins: Vec, -}