diff --git a/Cargo.lock b/Cargo.lock index 6d8e1dadd7..967762ef02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,18 +400,18 @@ dependencies = [ [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -495,7 +495,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -508,12 +507,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -883,9 +876,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" @@ -929,8 +922,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost 0.10.4", "prost-types 0.10.1", @@ -939,8 +933,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -961,11 +956,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.1" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -974,26 +969,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -1176,9 +1198,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1310,10 +1332,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1324,9 +1347,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1335,22 +1358,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1358,11 +1385,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1370,11 +1398,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1441,11 +1485,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1577,9 +1633,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1635,16 +1691,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1832,6 +1890,16 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "figment" version = "0.10.8" @@ -2216,6 +2284,17 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -2891,15 +2970,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] @@ -3903,6 +3981,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3941,7 +4021,7 @@ dependencies = [ "rand_chacha 0.3.1", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time 0.3.21", @@ -4027,7 +4107,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -5002,11 +5084,11 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -5154,13 +5236,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -5781,12 +5862,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -5805,6 +5886,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -6139,10 +6229,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -6230,6 +6321,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.5.0" @@ -6376,14 +6476,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -6427,11 +6525,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -6534,9 +6632,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -6903,9 +7001,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -6934,9 +7032,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -6948,9 +7046,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -6966,9 +7064,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 4f0e80d599..8e40379227 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,19 +117,21 @@ anyhow = "1.0.71" async-trait = "0.1.64" bip39 = { version = "2.0.0", features = ["zeroize"] } cfg-if = "1.0.0" -cosmwasm-derive = "=1.0.0" -cosmwasm-schema = "=1.0.0" -cosmwasm-std = "=1.0.0" -cosmwasm-storage = "=1.0.0" -cw-controllers = "=0.13.4" -cw-storage-plus = "=0.13.4" -cw-utils = "=0.13.4" -cw2 = { version = "=0.13.4" } -cw3 = { version = "=0.13.4" } -cw3-fixed-multisig = { version = "=0.13.4" } -cw4 = { version = "=0.13.4" } +cosmwasm-derive = "=1.2.5" +cosmwasm-schema = "=1.2.5" +cosmwasm-std = "=1.2.5" +cosmwasm-storage = "=1.2.5" +cosmrs = "=0.8.0" +cw-utils = "=1.0.1" +cw-storage-plus = "=1.0.1" +cw2 = { version = "=1.0.1" } +cw3 = { version = "=1.0.1" } +cw3-fixed-multisig = { version = "=1.0.1" } +cw4 = { version = "=1.0.1" } +cw-controllers = { version = "=1.0.1" } dotenvy = "0.15.6" generic-array = "0.14.7" +k256 = "0.11" getrandom = "0.2.10" lazy_static = "1.4.0" log = "0.4" diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 823fbbb252..ceef50ba14 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -237,18 +237,18 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -332,7 +332,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -345,12 +344,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -577,9 +570,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "constant_time_eq" @@ -605,8 +598,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -615,8 +609,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -637,11 +632,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -650,26 +645,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -783,9 +805,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -867,10 +889,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -881,9 +904,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -892,22 +915,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -915,11 +942,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -927,11 +955,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -953,11 +997,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1050,9 +1106,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1108,16 +1164,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1232,6 +1290,16 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "flate2" version = "1.0.26" @@ -1524,6 +1592,17 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -1978,15 +2057,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] @@ -2540,6 +2618,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -2556,7 +2636,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -2566,7 +2646,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -3085,11 +3167,11 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -3214,13 +3296,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -3549,12 +3630,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -3573,6 +3654,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -3742,10 +3832,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -3818,6 +3909,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.5.0" @@ -3953,14 +4053,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -3974,11 +4072,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -4048,9 +4146,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -4335,9 +4433,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -4366,9 +4464,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -4380,9 +4478,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -4398,9 +4496,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index e531f072d1..07d9ab5f5f 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -4,7 +4,7 @@ // due to expansion of #[wasm_bindgen] macro on `Debug` Config struct #![allow(clippy::drop_non_drop)] // another issue due to #[wasm_bindgen] and `Copy` trait -#![allow(clippy::drop_copy)] +#![allow(dropping_copy_types)] use nym_client_core::config::{ Acknowledgements as ConfigAcknowledgements, Config as BaseClientConfig, diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 3e0428e643..ac66916c46 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -41,7 +41,7 @@ nym-api-requests = { path = "../../../nym-api/nym-api-requests" } async-trait = { workspace = true, optional = true } bip39 = { workspace = true, features = ["rand"], optional = true } nym-config = { path = "../../config", optional = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"], optional = true } +cosmrs = { workspace = true, features = ["rpc", "bip32", "cosmwasm"], optional = true } # note that this has the same version as used by cosmrs eyre = { version = "0.6", optional = true } cw3 = { workspace = true, optional = true } @@ -55,7 +55,7 @@ cosmwasm-std = { workspace = true, optional = true } [dev-dependencies] bip39 = { workspace = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32"] } +cosmrs = { workspace = true, features = ["rpc", "bip32"] } tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } ts-rs = "6.1.2" diff --git a/common/client-libs/validator-client/src/nyxd/fee/mod.rs b/common/client-libs/validator-client/src/nyxd/fee/mod.rs index e1ee4b4d5c..6b857f8a66 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/mod.rs @@ -127,46 +127,13 @@ impl GasAdjustable for Gas { mod sealed { use cosmrs::tx::{self, Gas}; use cosmrs::Coin as CosmosCoin; - use cosmrs::{AccountId, Decimal as CosmosDecimal, Denom as CosmosDenom}; + use cosmrs::{AccountId, Denom as CosmosDenom}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - fn cosmos_denom_inner_getter(val: &CosmosDenom) -> String { - val.as_ref().to_string() - } - - #[derive(Serialize, Deserialize)] - #[serde(remote = "CosmosDenom")] - struct Denom(#[serde(getter = "cosmos_denom_inner_getter")] String); - - impl From for CosmosDenom { - fn from(val: Denom) -> Self { - val.0.parse().unwrap() - } - } - - fn cosmos_decimal_inner_getter(val: &CosmosDecimal) -> u64 { - // haha, this code is so disgusting. I'll make a PR on cosmrs to slightly alleviate those issues... - // note: unwrap here is fine as the to_string is just returning a stringified u64 which, well, is a valid u64 - val.to_string().parse().unwrap() - } - - // at the time of writing it the current cosmrs' Decimal is extremely limited... - #[derive(Serialize, Deserialize)] - #[serde(remote = "CosmosDecimal")] - struct Decimal(#[serde(getter = "cosmos_decimal_inner_getter")] u64); - - impl From for CosmosDecimal { - fn from(val: Decimal) -> Self { - val.0.into() - } - } - #[derive(Serialize, Deserialize, Clone)] struct Coin { - #[serde(with = "Denom")] denom: CosmosDenom, - #[serde(with = "Decimal")] - amount: CosmosDecimal, + amount: u128, } impl From for CosmosCoin { diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 58890e8621..0d90eb2387 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -39,7 +39,7 @@ pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo; pub use cosmrs::tendermint::Time as TendermintTime; pub use cosmrs::tx::{self, Gas}; pub use cosmrs::Coin as CosmosCoin; -pub use cosmrs::{bip32, AccountId, Decimal, Denom}; +pub use cosmrs::{bip32, AccountId, Denom}; use cosmwasm_std::Addr; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 9f77a9e4ae..d57e1c47ac 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -14,7 +14,7 @@ clap = { version = "4.0", features = ["derive"] } cw-utils = { workspace = true } handlebars = "3.0.1" humantime-serde = "1.0" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { workspace = true, features = ["ecdsa", "sha256"] } log = { workspace = true } rand = {version = "0.6", features = ["std"] } serde = { version = "1.0", features = ["derive"] } @@ -25,7 +25,7 @@ toml = "0.5.6" url = "2.2" tap = "1" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } cosmwasm-std = { workspace = true } nym-validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] } diff --git a/common/commands/src/validator/cosmwasm/generators/multisig.rs b/common/commands/src/validator/cosmwasm/generators/multisig.rs index cb610845c6..37f05a5e71 100644 --- a/common/commands/src/validator/cosmwasm/generators/multisig.rs +++ b/common/commands/src/validator/cosmwasm/generators/multisig.rs @@ -56,6 +56,8 @@ pub async fn generate(args: Args) { .expect("threshold can't be converted to Decimal"), }, max_voting_period: Duration::Time(args.max_voting_period), + executor: None, + proposal_deposit: None, coconut_bandwidth_contract_address: coconut_bandwidth_contract_address.to_string(), coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(), }; diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs index 20f1e2700d..8fffcc81eb 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs @@ -14,7 +14,7 @@ pub struct InstantiateMsg { pub mix_denom: String, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { DepositFunds { data: DepositData }, diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs index ffece73fd4..7cb47dc73b 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::msg::ExecuteMsg; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct SpendCredentialData { funds: Coin, blinded_serial_number: String, @@ -43,7 +43,7 @@ pub enum SpendCredentialStatus { Spent, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct SpendCredential { funds: Coin, blinded_serial_number: String, @@ -74,7 +74,7 @@ impl SpendCredential { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedSpendCredentialResponse { pub spend_credentials: Vec, pub per_page: usize, @@ -95,7 +95,7 @@ impl PagedSpendCredentialResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct SpendCredentialResponse { pub spend_credential: Option, } diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs b/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs index 206152957b..23018c9249 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs @@ -15,7 +15,7 @@ pub type Nonce = u32; // define this type explicitly for [hopefully] better usability // (so you wouldn't need to worry about whether you should use bytes, bs58, etc.) -#[derive(Clone, Debug, PartialEq, JsonSchema)] +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct MessageSignature(Vec); impl MessageSignature { diff --git a/common/cosmwasm-smart-contracts/group-contract/Cargo.toml b/common/cosmwasm-smart-contracts/group-contract/Cargo.toml index 9f57c84154..2856c44925 100644 --- a/common/cosmwasm-smart-contracts/group-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/group-contract/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cosmwasm-schema = { workspace = true } cw4 = { workspace = true } +cw-controllers = { workspace = true } schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs index a5a473135d..3f95227492 100644 --- a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs @@ -1,13 +1,7 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::{cw_serde, QueryResponses}; use cw4::Member; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct InstantiateMsg { /// The admin is the only account that can update the group state. /// Omit it to make the group immutable. @@ -15,8 +9,7 @@ pub struct InstantiateMsg { pub members: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { /// Change the admin UpdateAdmin { admin: Option }, @@ -32,23 +25,24 @@ pub enum ExecuteMsg { RemoveHook { addr: String }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return AdminResponse + #[returns(cw_controllers::AdminResponse)] Admin {}, - /// Return TotalWeightResponse - TotalWeight {}, - /// Returns MembersListResponse + #[returns(cw4::TotalWeightResponse)] + TotalWeight { at_height: Option }, + #[returns(cw4::MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - /// Returns MemberResponse + #[returns(cw4::MemberResponse)] Member { addr: String, at_height: Option, }, - /// Shows all registered hooks. Returns HooksResponse. + /// Shows all registered hooks. + #[returns(cw_controllers::HooksResponse)] Hooks {}, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs index 876ce7b515..55294498b8 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs @@ -37,7 +37,7 @@ pub fn generate_owner_storage_subkey( } } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct Delegation { /// Address of the owner of this delegation. pub owner: Addr, @@ -114,7 +114,7 @@ impl Delegation { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixNodeDelegationsResponse { pub delegations: Vec, pub start_next_after: Option, @@ -129,7 +129,7 @@ impl PagedMixNodeDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedDelegatorDelegationsResponse { pub delegations: Vec, pub start_next_after: Option<(MixId, OwnerProxySubKey)>, @@ -147,7 +147,7 @@ impl PagedDelegatorDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeDelegationResponse { pub delegation: Option, pub mixnode_still_bonded: bool, @@ -162,7 +162,7 @@ impl MixNodeDelegationResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedAllDelegationsResponse { pub delegations: Vec, pub start_next_after: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs index 5d39b2c150..c312d42bf7 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs @@ -23,7 +23,7 @@ pub struct Gateway { pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayBond { pub pledge_amount: Coin, pub owner: Addr, @@ -132,7 +132,7 @@ impl GatewayConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedGatewayResponse { pub nodes: Vec, pub per_page: usize, @@ -153,13 +153,13 @@ impl PagedGatewayResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayOwnershipResponse { pub address: Addr, pub gateway: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayBondResponse { pub identity: IdentityKey, pub gateway: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index fc2b14d71e..5afdbd827e 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs @@ -489,7 +489,7 @@ impl CurrentIntervalResponse { } } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct PendingEpochEventsResponse { pub seconds_until_executable: i64, pub events: Vec, @@ -510,7 +510,7 @@ impl PendingEpochEventsResponse { } } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct PendingIntervalEventsResponse { pub seconds_until_executable: i64, pub events: Vec, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 6d5ca55e7b..69f1a89209 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -33,7 +33,7 @@ impl RewardedSetNodeStatus { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeDetails { pub bond_information: MixNodeBond, pub rewarding_details: MixNodeRewarding, @@ -86,7 +86,7 @@ impl MixNodeDetails { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeRewarding { /// Information provided by the operator that influence the cost function. pub cost_params: MixNodeCostParams, @@ -465,7 +465,7 @@ impl MixNodeRewarding { } // operator information + data assigned by the contract(s) -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeBond { /// Unique id assigned to the bonded mixnode. pub mix_id: MixId, @@ -559,7 +559,7 @@ pub struct MixNode { pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeCostParams { pub profit_margin_percent: Percent, @@ -686,7 +686,7 @@ impl MixNodeConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixnodeBondsResponse { pub nodes: Vec, pub per_page: usize, @@ -703,7 +703,7 @@ impl PagedMixnodeBondsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixnodesDetailsResponse { pub nodes: Vec, pub per_page: usize, @@ -745,19 +745,19 @@ impl PagedUnbondedMixnodesResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixOwnershipResponse { pub address: Addr, pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixnodeDetailsResponse { pub mix_id: MixId, pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixnodeRewardingDetailsResponse { pub mix_id: MixId, pub rewarding_details: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs index 886c5b46b1..5f4db1ab90 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs @@ -7,19 +7,19 @@ use crate::{BlockHeight, EpochEventId, IntervalEventId, MixId}; use cosmwasm_std::{Addr, Coin}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingEpochEvent { pub id: EpochEventId, pub event: PendingEpochEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingEpochEventData { pub created_at: BlockHeight, pub kind: PendingEpochEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum PendingEpochEventKind { // can't just pass the `Delegation` struct here as it's impossible to determine // `cumulative_reward_ratio` ahead of time @@ -68,19 +68,19 @@ impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent { } } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingIntervalEvent { pub id: IntervalEventId, pub event: PendingIntervalEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingIntervalEventData { pub created_at: BlockHeight, pub kind: PendingIntervalEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum PendingIntervalEventKind { ChangeMixCostParams { mix_id: MixId, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs index ee091e6b13..650e39a2ff 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs @@ -35,7 +35,7 @@ pub struct RewardDistribution { pub delegates: Decimal, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] pub struct PendingRewardResponse { pub amount_staked: Option, pub amount_earned: Option, @@ -46,7 +46,7 @@ pub struct PendingRewardResponse { pub mixnode_still_fully_bonded: bool, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] pub struct EstimatedCurrentEpochRewardResponse { pub original_stake: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs index e1df97f04a..e0a8109f98 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs @@ -22,7 +22,7 @@ pub type EpochEventId = u32; pub type IntervalEventId = u32; #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq, Eq)] pub struct LayerAssignment { mix_id: MixId, layer: Layer, @@ -118,7 +118,7 @@ impl Index for LayerDistribution { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractState { pub owner: Addr, // only the owner account can update state pub rewarding_validator_address: Addr, @@ -130,7 +130,7 @@ pub struct ContractState { pub params: ContractStateParams, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractStateParams { /// Minimum amount a delegator must stake in orders for his delegation to get accepted. pub minimum_mixnode_delegation: Option, diff --git a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml index 4688654e1b..2a6753267e 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" cw-utils = { workspace = true } cw3 = { workspace = true } cw4 = { workspace= true } +cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs index b10fa6b506..ead941cad0 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use cosmwasm_std::StdError; -use cw_utils::ThresholdError; +use cw3::DepositError; +use cw_utils::{PaymentError, ThresholdError}; use thiserror::Error; @@ -17,9 +18,6 @@ pub enum ContractError { #[error("Group contract invalid address '{addr}'")] InvalidGroup { addr: String }, - #[error("Coconut bandwidth contract address not found")] - InvalidCoconutBandwidth {}, - #[error("Unauthorized")] Unauthorized {}, @@ -43,4 +41,10 @@ pub enum ContractError { #[error("Cannot close completed or passed proposals")] WrongCloseStatus {}, + + #[error("{0}")] + Payment(#[from] PaymentError), + + #[error("{0}")] + Deposit(#[from] DepositError), } diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs index a968ed14e5..64af48ecf9 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs @@ -1,2 +1,3 @@ pub mod error; pub mod msg; +pub mod state; diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs index db37835f64..15b959fa14 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs @@ -1,15 +1,15 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::Vote; +use cw3::{UncheckedDepositInfo, Vote}; use cw4::MemberChangedHookMsg; use cw_utils::{Duration, Expiration, Threshold}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +use crate::state::Executor; + +#[cw_serde] pub struct InstantiateMsg { // this is the group contract that contains the member list pub group_addr: String, @@ -17,11 +17,15 @@ pub struct InstantiateMsg { pub coconut_dkg_contract_address: String, pub threshold: Threshold, pub max_voting_period: Duration, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, + /// The cost of creating a proposal (if any). + pub proposal_deposit: Option, } // TODO: add some T variants? Maybe good enough as fixed Empty for now -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Propose { title: String, @@ -45,41 +49,44 @@ pub enum ExecuteMsg { } // We can also add this as a cw3 extension -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return ThresholdResponse + #[returns(cw_utils::ThresholdResponse)] Threshold {}, - /// Returns ProposalResponse + #[returns(cw3::ProposalResponse)] Proposal { proposal_id: u64 }, - /// Returns ProposalListResponse + #[returns(cw3::ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - /// Returns ProposalListResponse + #[returns(cw3::ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - /// Returns VoteResponse + #[returns(cw3::VoteResponse)] Vote { proposal_id: u64, voter: String }, - /// Returns VoteListResponse + #[returns(cw3::VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - /// Returns VoterInfo + #[returns(cw3::VoterResponse)] Voter { address: String }, - /// Returns VoterListResponse + #[returns(cw3::VoterListResponse)] ListVoters { start_after: Option, limit: Option, }, + /// Gets the current configuration. + #[returns(crate::state::Config)] + Config {}, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] + +#[cw_serde] pub struct MigrateMsg { pub coconut_bandwidth_address: String, pub coconut_dkg_address: String, diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs new file mode 100644 index 0000000000..d3ce181ba1 --- /dev/null +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs @@ -0,0 +1,59 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, QuerierWrapper}; +use cw3::DepositInfo; +use cw4::Cw4Contract; +use cw_storage_plus::Item; +use cw_utils::{Duration, Threshold}; + +use crate::error::ContractError; + +/// Defines who is able to execute proposals once passed +#[cw_serde] +pub enum Executor { + /// Any member of the voting group, even with 0 points + Member, + /// Only the given address + Only(Addr), +} + +#[cw_serde] +pub struct Config { + pub threshold: Threshold, + pub max_voting_period: Duration, + // Total weight and voters are queried from this contract + pub group_addr: Cw4Contract, + pub coconut_bandwidth_addr: Addr, + pub coconut_dkg_addr: Addr, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, + /// The price, if any, of creating a new proposal. + pub proposal_deposit: Option, +} + +impl Config { + // Executor can be set in 3 ways: + // - Member: any member of the voting group is authorized + // - Only: only passed address is authorized + // - None: Everyone are authorized + pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> { + if let Some(executor) = &self.executor { + match executor { + Executor::Member => { + self.group_addr + .is_member(querier, sender, None)? + .ok_or(ContractError::Unauthorized {})?; + } + Executor::Only(addr) => { + if addr != sender { + return Err(ContractError::Unauthorized {}); + } + } + } + } + Ok(()) + } +} + +// unique items +pub const CONFIG: Item = Item::new("config"); diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs index 75d916ddad..6c456674a5 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs @@ -28,7 +28,7 @@ pub enum Period { After, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct PledgeData { pub amount: Coin, pub block_time: Timestamp, @@ -49,7 +49,7 @@ impl PledgeData { } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub enum PledgeCap { Percent(Percent), Absolute(Uint128), // This has to be in unym @@ -77,7 +77,7 @@ impl Default for PledgeCap { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct OriginalVestingResponse { pub amount: Coin, pub number_of_periods: usize, diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs index 226f39a9c0..f4d7147e2c 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs @@ -55,7 +55,7 @@ impl VestingSpecification { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { // Families diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 3f029494dd..6bb10d5cb6 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } thiserror = "1.0" # I guess temporarily until we get serde support in coconut up and running diff --git a/common/ledger/Cargo.toml b/common/ledger/Cargo.toml index 9bea382a73..dda242bf14 100644 --- a/common/ledger/Cargo.toml +++ b/common/ledger/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bip32 = "0.3.0" -k256 = "0.10.4" +bip32 = "0.4.0" +k256 = { workspace = true } ledger-transport = "0.10.0" ledger-transport-hid = "0.10.0" thiserror = "1" \ No newline at end of file diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index 2c106260c2..0dd4879310 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -20,7 +20,7 @@ url = "2.2" ts-rs = "6.1.2" cosmwasm-std = { workspace = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ "nyxd-client", diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 1db4c0bd8a..0c3efd0a24 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -50,9 +50,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", "arrayvec", @@ -260,23 +260,23 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -285,45 +285,62 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" dependencies = [ + "cosmwasm-schema-derive", "schemars", + "serde", "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] [[package]] name = "cosmwasm-storage" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" +checksum = "a3737a3aac48f5ed883b5b73bfb731e77feebd8fc6b43419844ec2971072164d" dependencies = [ "cosmwasm-std", "serde", @@ -361,9 +378,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", @@ -374,9 +391,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -389,9 +406,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.6", "rand_core 0.6.4", @@ -454,10 +471,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -468,17 +486,17 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.4" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f9a8ab7c3c29ec93cb7a39ce4b14a05e053153b4a17ef7cf2246af1b7c087e" +checksum = "2a18afd2e201221c6d72a57f0886ef2a22151bbc9e6db7af276fde8a91081042" dependencies = [ "anyhow", "cosmwasm-std", - "cosmwasm-storage", "cw-storage-plus", "cw-utils", "derivative", "itertools", + "k256", "prost", "schemars", "serde", @@ -487,9 +505,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -498,22 +516,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -521,11 +543,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -533,11 +556,45 @@ dependencies = [ ] [[package]] -name = "cw3-fixed-multisig" -version = "0.13.4" +name = "cw20-base" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54aa54c13f405ec4ab36b6217538bc957d439eee58f89312db05a79caf6706" +checksum = "afcd279230b08ed8afd8be5828221622bd5b9ce25d0b01d58bad626c6ce0169c" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3-fixed-multisig" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e2415adb201e5e89dab34edf59d7dc166bc558526de009a49ae66276c9119a" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -550,14 +607,15 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.1" +version = "1.0.0" dependencies = [ - "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", + "cw20", + "cw20-base", "cw3", "cw3-fixed-multisig", "cw4", @@ -565,15 +623,15 @@ dependencies = [ "nym-group-contract-common", "nym-multisig-contract-common", "schemars", - "serde", ] [[package]] name = "cw4" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -582,7 +640,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.4" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -599,11 +657,12 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", ] [[package]] @@ -654,9 +713,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -683,7 +742,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -698,7 +757,7 @@ dependencies = [ "hex", "rand_core 0.6.4", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -710,16 +769,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", + "digest 0.10.7", "ff", "generic-array 0.14.6", "group", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -778,9 +839,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", "subtle 2.4.1", @@ -974,9 +1035,9 @@ dependencies = [ [[package]] name = "group" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", @@ -992,15 +1053,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.1" @@ -1020,7 +1072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest 0.9.0", - "hmac", + "hmac 0.11.0", ] [[package]] @@ -1033,6 +1085,15 @@ dependencies = [ "digest 0.9.0", ] +[[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 = "humantime" version = "2.1.0" @@ -1083,7 +1144,7 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -1123,15 +1184,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2", + "sha2 0.10.6", ] [[package]] @@ -1217,9 +1277,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -1252,11 +1312,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1347,6 +1407,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -1387,7 +1449,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -1397,7 +1459,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -1595,13 +1659,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -1827,12 +1890,12 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -1941,10 +2004,11 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.6", "pkcs8", @@ -1976,6 +2040,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.160" @@ -2034,12 +2107,23 @@ dependencies = [ ] [[package]] -name = "signature" -version = "1.4.0" +name = "sha2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "digest 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -2067,20 +2151,20 @@ dependencies = [ "curve25519-dalek", "digest 0.9.0", "hkdf", - "hmac", + "hmac 0.11.0", "lioness", "log", "rand 0.7.3", "rand_distr", - "sha2", + "sha2 0.9.9", "subtle 2.4.1", ] [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 9d1fb0ac6a..1b20380ad7 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -32,16 +32,17 @@ incremental = false overflow-checks = true [workspace.dependencies] -cosmwasm-crypto = "=1.0.0" -cosmwasm-derive = "=1.0.0" -cosmwasm-schema = "=1.0.0" -cosmwasm-std = "=1.0.0" -cosmwasm-storage = "=1.0.0" -cw-controllers = "=0.13.4" -cw-multi-test = "=0.13.4" -cw-storage-plus = "=0.13.4" -cw-utils = "=0.13.4" -cw2 = "=0.13.4" -cw3 = "=0.13.4" -cw3-fixed-multisig = "=0.13.4" -cw4 = "=0.13.4" +cosmwasm-crypto = "=1.2.5" +cosmwasm-derive = "=1.2.5" +cosmwasm-schema = "=1.2.5" +cosmwasm-std = "=1.2.5" +cosmwasm-storage = "=1.2.5" +cw-controllers = "=1.0.1" +cw-multi-test = "=0.16.4" +cw-storage-plus = "=1.0.1" +cw-utils = "=1.0.1" +cw2 = "=1.0.1" +cw3 = "=1.0.1" +cw3-fixed-multisig = "=1.0.1" +cw4 = "=1.0.1" +cw20 = "=1.0.1" diff --git a/contracts/coconut-dkg/src/verification_key_shares/storage.rs b/contracts/coconut-dkg/src/verification_key_shares/storage.rs index fae9a59d10..51a7fbb03e 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/storage.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/storage.rs @@ -30,7 +30,7 @@ impl<'a> IndexList for VkShareIndex<'a> { pub(crate) fn vk_shares<'a>() -> IndexedMap<'a, VKShareKey<'a>, ContractVKShare, VkShareIndex<'a>> { let indexes = VkShareIndex { epoch_id: MultiIndex::new( - |d| d.epoch_id, + |_pk, d| d.epoch_id, VK_SHARES_PK_NAMESPACE, VK_SHARES_EPOCH_ID_IDX_NAMESPACE, ), diff --git a/contracts/coconut-test/src/helpers.rs b/contracts/coconut-test/src/helpers.rs index c679176177..e0f667612d 100644 --- a/contracts/coconut-test/src/helpers.rs +++ b/contracts/coconut-test/src/helpers.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use cosmwasm_std::{entry_point, Addr, Coin, DepsMut, Empty, Env, Response}; -use cw3_flex_multisig::state::CONFIG; use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper}; use nym_multisig_contract_common::error::ContractError; +use nym_multisig_contract_common::state::CONFIG; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/contracts/coconut-test/src/spend_credential_creates_proposal.rs b/contracts/coconut-test/src/spend_credential_creates_proposal.rs index 317f28a024..abcf761da5 100644 --- a/contracts/coconut-test/src/spend_credential_creates_proposal.rs +++ b/contracts/coconut-test/src/spend_credential_creates_proposal.rs @@ -45,6 +45,8 @@ fn spend_credential_creates_proposal() { threshold: Threshold::AbsolutePercentage { percentage: Decimal::from_ratio(2u128, 3u128), }, + executor: None, + proposal_deposit: None, max_voting_period: Duration::Height(1000), coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), diff --git a/contracts/coconut-test/src/submit_vk_creates_proposal.rs b/contracts/coconut-test/src/submit_vk_creates_proposal.rs index d111b1f0c7..4e1d5dc346 100644 --- a/contracts/coconut-test/src/submit_vk_creates_proposal.rs +++ b/contracts/coconut-test/src/submit_vk_creates_proposal.rs @@ -52,6 +52,8 @@ fn dkg_proposal() { threshold: Threshold::AbsolutePercentage { percentage: Decimal::from_ratio(1u128, 1u128), }, + executor: None, + proposal_deposit: None, max_voting_period: Duration::Time(1000), coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), diff --git a/contracts/mixnet/src/delegations/queries.rs b/contracts/mixnet/src/delegations/queries.rs index 0de9d151cf..5a5d07c32f 100644 --- a/contracts/mixnet/src/delegations/queries.rs +++ b/contracts/mixnet/src/delegations/queries.rs @@ -520,7 +520,7 @@ mod tests { .delegations .iter() .filter(|d| d.proxy.is_some()) - .all(|d| d.proxy.as_ref().unwrap() == &vesting_contract)); + .all(|d| d.proxy.as_ref().unwrap() == vesting_contract)); // now make sure that if we do it in paged manner, we'll get exactly the same result let per_page = Some(15); diff --git a/contracts/mixnet/src/delegations/storage.rs b/contracts/mixnet/src/delegations/storage.rs index b74bb870b0..5d3e6b45f2 100644 --- a/contracts/mixnet/src/delegations/storage.rs +++ b/contracts/mixnet/src/delegations/storage.rs @@ -27,12 +27,12 @@ impl<'a> IndexList for DelegationIndex<'a> { pub(crate) fn delegations<'a>() -> IndexedMap<'a, PrimaryKey, Delegation, DelegationIndex<'a>> { let indexes = DelegationIndex { owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), DELEGATION_PK_NAMESPACE, DELEGATION_OWNER_IDX_NAMESPACE, ), mixnode: MultiIndex::new( - |d| d.mix_id, + |_pk, d| d.mix_id, DELEGATION_PK_NAMESPACE, DELEGATION_MIXNODE_IDX_NAMESPACE, ), diff --git a/contracts/mixnet/src/mixnodes/storage.rs b/contracts/mixnet/src/mixnodes/storage.rs index fdf744e0bd..2007456463 100644 --- a/contracts/mixnet/src/mixnodes/storage.rs +++ b/contracts/mixnet/src/mixnodes/storage.rs @@ -39,12 +39,12 @@ pub(crate) fn unbonded_mixnodes<'a>( ) -> IndexedMap<'a, MixId, UnbondedMixnode, UnbondedMixnodeIndex<'a>> { let indexes = UnbondedMixnodeIndex { owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), UNBONDED_MIXNODES_PK_NAMESPACE, UNBONDED_MIXNODES_OWNER_IDX_NAMESPACE, ), identity_key: MultiIndex::new( - |d| d.identity_key.clone(), + |_pk, d| d.identity_key.clone(), UNBONDED_MIXNODES_PK_NAMESPACE, UNBONDED_MIXNODES_IDENTITY_IDX_NAMESPACE, ), diff --git a/contracts/mixnet/src/rewards/transactions.rs b/contracts/mixnet/src/rewards/transactions.rs index b73c66a499..19ca0e8c83 100644 --- a/contracts/mixnet/src/rewards/transactions.rs +++ b/contracts/mixnet/src/rewards/transactions.rs @@ -185,7 +185,7 @@ pub(crate) fn _try_withdraw_operator_reward( // we can only attempt to send the message to the vesting contract if the proxy IS the vesting contract // otherwise, we don't care let vesting_contract = mixnet_params_storage::vesting_contract_address(deps.storage)?; - if proxy == &vesting_contract { + if proxy == vesting_contract { let msg = VestingContractExecuteMsg::TrackReward { amount: reward.clone(), address: owner.clone().into_string(), @@ -271,7 +271,7 @@ pub(crate) fn _try_withdraw_delegator_reward( // we can only attempt to send the message to the vesting contract if the proxy IS the vesting contract // otherwise, we don't care let vesting_contract = mixnet_params_storage::vesting_contract_address(deps.storage)?; - if proxy == &vesting_contract { + if proxy == vesting_contract { let msg = VestingContractExecuteMsg::TrackReward { amount: reward.clone(), address: owner.clone().into_string(), diff --git a/contracts/mixnet/src/support/helpers.rs b/contracts/mixnet/src/support/helpers.rs index e39541f599..094d96eaba 100644 --- a/contracts/mixnet/src/support/helpers.rs +++ b/contracts/mixnet/src/support/helpers.rs @@ -298,7 +298,7 @@ pub(crate) fn ensure_is_authorized( sender: &Addr, storage: &dyn Storage, ) -> Result<(), MixnetContractError> { - if sender != &crate::mixnet_contract_settings::storage::rewarding_validator_address(storage)? { + if sender != crate::mixnet_contract_settings::storage::rewarding_validator_address(storage)? { return Err(MixnetContractError::Unauthorized); } Ok(()) @@ -309,7 +309,7 @@ pub(crate) fn ensure_can_advance_epoch( storage: &dyn Storage, ) -> Result { let epoch_status = crate::interval::storage::current_epoch_status(storage)?; - if sender != &epoch_status.being_advanced_by { + if sender != epoch_status.being_advanced_by { // well, we know we're going to throw an error now, // but we might as well also check if we're even a validator // to return a possibly better error message diff --git a/contracts/multisig/cw3-flex-multisig/Cargo.toml b/contracts/multisig/cw3-flex-multisig/Cargo.toml index 0c45bb149d..b849828069 100644 --- a/contracts/multisig/cw3-flex-multisig/Cargo.toml +++ b/contracts/multisig/cw3-flex-multisig/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "cw3-flex-multisig" -version = "0.13.1" +version = "1.0.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" @@ -13,6 +13,7 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] +backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] @@ -22,15 +23,15 @@ cw2 = { workspace = true } cw3 = { workspace = true } cw3-fixed-multisig = { workspace = true, features = ["library"] } cw4 = { workspace = true } +cw20 = { workspace = true } cw-storage-plus = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" } nym-multisig-contract-common = { path= "../../../common/cosmwasm-smart-contracts/multisig-contract" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } -cw4-group = { path = "../cw4-group", version = "0.13.4" } +cw4-group = { path = "../cw4-group", version = "1.0.0" } cw-multi-test = { workspace = true } +cw20-base = "1.0.0" diff --git a/contracts/multisig/cw3-flex-multisig/src/contract.rs b/contracts/multisig/cw3-flex-multisig/src/contract.rs index 24c460b0a2..9a0c8eacad 100644 --- a/contracts/multisig/cw3-flex-multisig/src/contract.rs +++ b/contracts/multisig/cw3-flex-multisig/src/contract.rs @@ -8,18 +8,19 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; + use cw3::{ - ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, - VoterDetail, VoterListResponse, VoterResponse, + Ballot, Proposal, ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, + VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, Votes, }; -use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; +use cw3_fixed_multisig::state::{next_id, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; -use crate::state::{Config, CONFIG}; use nym_multisig_contract_common::error::ContractError; use nym_multisig_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use nym_multisig_contract_common::state::{Config, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; @@ -46,6 +47,11 @@ pub fn instantiate( let total_weight = group_addr.total_weight(&deps.querier)?; msg.threshold.validate(total_weight)?; + let proposal_deposit = msg + .proposal_deposit + .map(|deposit| deposit.into_checked(deps.as_ref())) + .transpose()?; + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { @@ -54,21 +60,14 @@ pub fn instantiate( group_addr, coconut_bandwidth_addr, coconut_dkg_addr, + executor: msg.executor, + proposal_deposit, }; CONFIG.save(deps.storage, &cfg)?; Ok(Response::default()) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result { - let mut cfg = CONFIG.load(deps.storage)?; - cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?; - cfg.coconut_dkg_addr = deps.api.addr_validate(&msg.coconut_dkg_address)?; - CONFIG.save(deps.storage, &cfg)?; - Ok(Default::default()) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, @@ -105,6 +104,11 @@ pub fn execute_propose( // only members of the multisig can create a proposal let cfg = CONFIG.load(deps.storage)?; + // Check that the native deposit was paid (as needed). + if let Some(deposit) = cfg.proposal_deposit.as_ref() { + deposit.check_native_deposit_paid(&info)?; + } + // Only the coconut bandwidth or dkg contracts can create proposals if info.sender != cfg.coconut_bandwidth_addr && info.sender != cfg.coconut_dkg_addr { return Err(ContractError::Unauthorized {}); @@ -122,6 +126,15 @@ pub fn execute_propose( return Err(ContractError::WrongExpiration {}); } + // Take the cw20 token deposit, if required. We do this before + // creating the proposal struct below so that we can avoid a clone + // and move the loaded deposit info into it. + let take_deposit_msg = if let Some(deposit_info) = cfg.proposal_deposit.as_ref() { + deposit_info.get_take_deposit_messages(&info.sender, &env.contract.address)? + } else { + vec![] + }; + // create a proposal let mut prop = Proposal { title, @@ -133,6 +146,8 @@ pub fn execute_propose( votes: Votes::yes(vote_power), threshold: cfg.threshold, total_weight: cfg.group_addr.total_weight(&deps.querier)?, + proposer: info.sender.clone(), + deposit: cfg.proposal_deposit, }; prop.update_status(&env.block); let id = next_id(deps.storage)?; @@ -146,6 +161,7 @@ pub fn execute_propose( BALLOTS.save(deps.storage, (id, &info.sender), &ballot)?; Ok(Response::new() + .add_messages(take_deposit_msg) .add_attribute("action", "propose") .add_attribute("sender", info.sender) .add_attribute("proposal_id", id.to_string()) @@ -164,9 +180,11 @@ pub fn execute_vote( // ensure proposal exists and can be voted on let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if prop.status != Status::Open { + // Allow voting on Passed and Rejected proposals too, + if ![Status::Open, Status::Passed, Status::Rejected].contains(&prop.status) { return Err(ContractError::NotOpen {}); } + // if they are not expired if prop.expires.is_expired(&env.block) { return Err(ContractError::Expired {}); } @@ -206,21 +224,31 @@ pub fn execute_execute( info: MessageInfo, proposal_id: u64, ) -> Result { - // anyone can trigger this if the vote passed - let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.current_status(&env.block) != Status::Passed { + prop.update_status(&env.block); + if prop.status != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } + let cfg = CONFIG.load(deps.storage)?; + cfg.authorize(&deps.querier, &info.sender)?; + // set it to executed prop.status = Status::Executed; PROPOSALS.save(deps.storage, proposal_id, &prop)?; + // Unconditionally refund here. + let response = match prop.deposit { + Some(deposit) => { + Response::new().add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + None => Response::new(), + }; + // dispatch all proposed messages - Ok(Response::new() + Ok(response .add_messages(prop.msgs) .add_attribute("action", "execute") .add_attribute("sender", info.sender) @@ -236,10 +264,11 @@ pub fn execute_close( // anyone can trigger this if the vote passed let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if [Status::Executed, Status::Rejected, Status::Passed] - .iter() - .any(|x| *x == prop.status) - { + if [Status::Executed, Status::Rejected, Status::Passed].contains(&prop.status) { + return Err(ContractError::WrongCloseStatus {}); + } + // Avoid closing of Passed due to expiration proposals + if prop.current_status(&env.block) == Status::Passed { return Err(ContractError::WrongCloseStatus {}); } if !prop.expires.is_expired(&env.block) { @@ -250,7 +279,15 @@ pub fn execute_close( prop.status = Status::Rejected; PROPOSALS.save(deps.storage, proposal_id, &prop)?; - Ok(Response::new() + // Refund the deposit if we have been configured to do so. + let mut response = Response::new(); + if let Some(deposit) = prop.deposit { + if deposit.refund_failed_proposals { + response = response.add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + } + + Ok(response .add_attribute("action", "close") .add_attribute("sender", info.sender) .add_attribute("proposal_id", proposal_id.to_string())) @@ -294,6 +331,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ListVoters { start_after, limit } => { to_binary(&list_voters(deps, start_after, limit)?) } + QueryMsg::Config {} => to_binary(&query_config(deps)?), } } @@ -303,6 +341,10 @@ fn query_threshold(deps: Deps) -> StdResult { Ok(cfg.threshold.to_response(total_weight)) } +fn query_config(deps: Deps) -> StdResult { + CONFIG.load(deps.storage) +} + fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult { let prop = PROPOSALS.load(deps.storage, id)?; let status = prop.current_status(&env.block); @@ -314,6 +356,8 @@ fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult msgs: prop.msgs, status, expires: prop.expires, + proposer: prop.proposer, + deposit: prop.deposit, threshold, }) } @@ -370,6 +414,8 @@ fn map_proposal( msgs: prop.msgs, status, expires: prop.expires, + deposit: prop.deposit, + proposer: prop.proposer, threshold, } }) @@ -440,15 +486,26 @@ fn list_voters( Ok(VoterListResponse { voters }) } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result { + let mut cfg = CONFIG.load(deps.storage)?; + cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?; + cfg.coconut_dkg_addr = deps.api.addr_validate(&msg.coconut_dkg_address)?; + CONFIG.save(deps.storage, &cfg)?; + Ok(Default::default()) +} + #[cfg(test)] mod tests { - use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp}; + use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp, Uint128}; use cw2::{query_contract_info, ContractVersion}; + use cw20::{Cw20Coin, UncheckedDenom}; + use cw3::{DepositError, UncheckedDepositInfo}; use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; use cw_multi_test::{ - next_block, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, + next_block, App, AppBuilder, BankSudo, Contract, ContractWrapper, Executor, SudoMsg, }; use cw_utils::{Duration, Threshold}; @@ -461,9 +518,8 @@ mod tests { const VOTER4: &str = "voter0004"; const VOTER5: &str = "voter0005"; const SOMEBODY: &str = "somebody"; - const TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = - "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; - const TEST_COCONUT_DKG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; + const BANDWIDTH_CONTRACT: &str = "coconut_bandwidth_addr"; + const DKG_CONTRACT: &str = "coconut_dkg_addr"; fn member>(addr: T, weight: u64) -> Member { Member { @@ -490,6 +546,15 @@ mod tests { Box::new(contract) } + fn contract_cw20() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) + } + fn mock_app(init_funds: &[Coin]) -> App { AppBuilder::new().build(|router, _, storage| { router @@ -510,40 +575,27 @@ mod tests { .unwrap() } - fn propose_and_vote( - app: &mut App, - flex_addr: Addr, - proposal: ExecuteMsg, - voter: &str, - ) -> AppResponse { - let proposer = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - let res = app - .execute_contract(Addr::unchecked(proposer), flex_addr.clone(), &proposal, &[]) - .unwrap(); - - let yes_vote = ExecuteMsg::Vote { - proposal_id: res.custom_attrs(1)[2].value.parse().unwrap(), - vote: Vote::Yes, - }; - let _ = app.execute_contract(Addr::unchecked(voter), flex_addr, &yes_vote, &[]); - - res - } - + #[allow(clippy::too_many_arguments)] #[track_caller] fn instantiate_flex( app: &mut App, group: Addr, + coconut_bandwidth_contract_address: Addr, + coconut_dkg_contract_address: Addr, threshold: Threshold, max_voting_period: Duration, + executor: Option, + proposal_deposit: Option, ) -> Addr { let flex_id = app.store_code(contract_flex()); let msg = InstantiateMsg { group_addr: group.to_string(), + coconut_bandwidth_contract_address: coconut_bandwidth_contract_address.to_string(), + coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(), threshold, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor, + proposal_deposit, }; app.instantiate_contract(flex_id, Addr::unchecked(OWNER), &msg, &[], "flex", None) .unwrap() @@ -568,6 +620,8 @@ mod tests { max_voting_period, init_funds, multisig_as_group_admin, + None, + None, ) } @@ -578,11 +632,11 @@ mod tests { max_voting_period: Duration, init_funds: Vec, multisig_as_group_admin: bool, + executor: Option, + proposal_deposit: Option, ) -> (Addr, Addr) { - let coconut_bandwidth_contract = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - // 1. Instantiate group contract with members (and OWNER as admin) and coconut bandwidth contract + // 1. Instantiate group contract with members (and OWNER as admin) let members = vec![ - member(coconut_bandwidth_contract, 0), member(OWNER, 0), member(VOTER1, 1), member(VOTER2, 2), @@ -594,7 +648,16 @@ mod tests { app.update_block(next_block); // 2. Set up Multisig backed by this group - let flex_addr = instantiate_flex(app, group_addr.clone(), threshold, max_voting_period); + let flex_addr = instantiate_flex( + app, + group_addr.clone(), + Addr::unchecked(BANDWIDTH_CONTRACT), + Addr::unchecked(DKG_CONTRACT), + threshold, + max_voting_period, + executor, + proposal_deposit, + ); app.update_block(next_block); // 3. (Optional) Set the multisig as the group owner @@ -641,6 +704,16 @@ mod tests { } } + fn text_proposal() -> ExecuteMsg { + let (_, title, description) = proposal_info(); + ExecuteMsg::Propose { + title, + description, + msgs: vec![], + latest: None, + } + } + #[test] fn test_instantiate_works() { let mut app = mock_app(&[]); @@ -654,13 +727,15 @@ mod tests { // Zero required weight fails let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::ThresholdQuorum { threshold: Decimal::zero(), quorum: Decimal::percent(1), }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -680,10 +755,12 @@ mod tests { // Total weight less than required weight not allowed let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::AbsoluteCount { weight: 100 }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -703,10 +780,12 @@ mod tests { // All valid let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::AbsoluteCount { weight: 1 }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let flex_addr = app .instantiate_contract( @@ -720,7 +799,7 @@ mod tests { .unwrap(); // Verify contract version set properly - let version = query_contract_info(&app, flex_addr.clone()).unwrap(); + let version = query_contract_info(&app.wrap(), flex_addr.clone()).unwrap(); assert_eq!( ContractVersion { contract: CONTRACT_NAME.to_string(), @@ -760,7 +839,7 @@ mod tests { setup_test_case_fixed(&mut app, required_weight, voting_period, init_funds, false); let proposal = pay_somebody_proposal(); - // Only voters can propose + // Only special addresses can propose let err = app .execute_contract(Addr::unchecked(SOMEBODY), flex_addr.clone(), &proposal, &[]) .unwrap_err(); @@ -779,13 +858,44 @@ mod tests { }; let err = app .execute_contract( - Addr::unchecked(TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string()), - flex_addr, + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), &proposal_wrong_exp, &[], ) .unwrap_err(); assert_eq!(ContractError::WrongExpiration {}, err.downcast().unwrap()); + + // Proposal from special address works + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "propose"), + ("sender", BANDWIDTH_CONTRACT), + ("proposal_id", "1"), + ("status", "Open"), + ], + ); + let res = app + .execute_contract(Addr::unchecked(DKG_CONTRACT), flex_addr, &proposal, &[]) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "propose"), + ("sender", DKG_CONTRACT), + ("proposal_id", "2"), + ("status", "Open"), + ], + ); } fn get_tally(app: &App, flex_addr: &str, proposal_id: u64) -> u64 { @@ -826,49 +936,6 @@ mod tests { } } - #[test] - fn test_proposer_limited_to_coconut_bandwidth() { - let init_funds = coins(10, "BTC"); - let mut app = mock_app(&init_funds); - - let voting_period = Duration::Time(2000000); - let threshold = Threshold::ThresholdQuorum { - threshold: Decimal::percent(80), - quorum: Decimal::percent(20), - }; - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); - let proposal = pay_somebody_proposal(); - - let err = app - .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let err = app - .execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let err = app - .execute_contract(Addr::unchecked(SOMEBODY), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let proposer = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - let res = app - .execute_contract(Addr::unchecked(&proposer), flex_addr, &proposal, &[]) - .unwrap(); - assert_eq!( - res.custom_attrs(1), - [ - ("action", "propose"), - ("sender", &proposer), - ("proposal_id", "1"), - ("status", "Open"), - ], - ); - } - #[test] fn test_proposal_queries() { let init_funds = coins(10, "BTC"); @@ -879,26 +946,73 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }; - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 1 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id1: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id1, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // another proposal immediately passes app.update_block(next_block); let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER4); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // expire them both app.update_block(expire(voting_period)); // add one more open proposal, 2 votes let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER2); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id3: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id3, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER2), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let proposed_at = app.block_info(); // next block, let's query them all... make sure status is properly updated (1 should be rejected in query) @@ -954,6 +1068,8 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }, + proposer: Addr::unchecked(BANDWIDTH_CONTRACT), + deposit: None, }; assert_eq!(&expected, &res.proposals[0]); } @@ -968,11 +1084,26 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1066,13 +1197,38 @@ mod tests { ], ); - // non-Open proposals cannot be voted - let err = app + // Passed proposals can still be voted (while they are not expired or executed) + let res = app .execute_contract(Addr::unchecked(VOTER5), flex_addr.clone(), &yes_vote, &[]) - .unwrap_err(); - assert_eq!(ContractError::NotOpen {}, err.downcast().unwrap()); + .unwrap(); + // Verify + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Passed") + ] + ); // query individual votes + // initial (with 0 weight) + let voter = BANDWIDTH_CONTRACT.into(); + let vote: VoteResponse = app + .wrap() + .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) + .unwrap(); + assert_eq!( + vote.vote.unwrap(), + VoteInfo { + proposal_id, + voter: BANDWIDTH_CONTRACT.into(), + vote: Vote::Yes, + weight: 0 + } + ); + // nay sayer let voter = VOTER2.into(); let vote: VoteResponse = app @@ -1090,7 +1246,7 @@ mod tests { ); // non-voter - let voter = VOTER5.into(); + let voter = SOMEBODY.into(); let vote: VoteResponse = app .wrap() .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) @@ -1099,7 +1255,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1115,7 +1278,7 @@ mod tests { // Powerful voter opposes it, so it rejects let res = app - .execute_contract(Addr::unchecked(VOTER4), flex_addr, &no_vote, &[]) + .execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &no_vote, &[]) .unwrap(); assert_eq!( @@ -1127,6 +1290,25 @@ mod tests { ("status", "Rejected"), ], ); + + // Rejected proposals can still be voted (while they are not expired) + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let res = app + .execute_contract(Addr::unchecked(VOTER5), flex_addr, &yes_vote, &[]) + .unwrap(); + + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Rejected"), + ], + ); } #[test] @@ -1139,7 +1321,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // ensure we have cash to cover the proposal let contract_bal = app.wrap().query_balance(&flex_addr, "BTC").unwrap(); @@ -1147,7 +1337,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1227,6 +1424,142 @@ mod tests { ); } + #[test] + fn execute_with_executor_member() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(nym_multisig_contract_common::state::Executor::Member), // set executor as Member of voting group + None, + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER2)), // member of voting group is allowed to execute + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + + #[test] + fn execute_with_executor_only() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(nym_multisig_contract_common::state::Executor::Only( + Addr::unchecked(VOTER3), + )), // only VOTER3 can execute proposal + None, + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked(VOTER1)), // VOTER1 is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER3)), // VOTER3 is allowed to execute + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + #[test] fn proposal_pass_on_expiration() { let init_funds = coins(10, "BTC"); @@ -1243,6 +1576,8 @@ mod tests { Duration::Time(voting_period), init_funds, true, + None, + None, ); // ensure we have cash to cover the proposal @@ -1251,7 +1586,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1287,6 +1629,17 @@ mod tests { .unwrap(); assert_eq!(prop.status, Status::Passed); + // Closing should NOT be possible + let err = app + .execute_contract( + Addr::unchecked(SOMEBODY), + flex_addr.clone(), + &ExecuteMsg::Close { proposal_id }, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::WrongCloseStatus {}, err.downcast().unwrap()); + // Execution should now be possible. let res = app .execute_contract( @@ -1316,11 +1669,26 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Height(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1365,14 +1733,34 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER1 starts a proposal to send some tokens (1/4 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App, proposal_id: u64| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1430,9 +1818,22 @@ mod tests { // make a second proposal let proposal2 = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal2, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal2, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // VOTER2 can pass this alone with the updated vote (newer height ignores snapshot) let yes_vote = ExecuteMsg::Vote { @@ -1500,18 +1901,44 @@ mod tests { msgs: vec![update_msg], latest: None, }; - let res = propose_and_vote(&mut app, flex_addr.clone(), update_proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &update_proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let update_proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: update_proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // next block... app.update_block(|b| b.height += 1); // VOTER1 starts a proposal to send some tokens let cash_proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), cash_proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &cash_proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let cash_proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: cash_proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); assert_ne!(cash_proposal_id, update_proposal_id); // query proposal state @@ -1593,14 +2020,34 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER3 starts a proposal to send some tokens (3/12 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER3); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER3), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1640,9 +2087,22 @@ mod tests { // new proposal can be passed single-handedly by newbie let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, newbie); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(newbie), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // check proposal2 status let query_prop = QueryMsg::Proposal { @@ -1673,13 +2133,28 @@ mod tests { voting_period, init_funds, false, + None, + None, ); // VOTER3 starts a proposal to send some tokens (3 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER3); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER3), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1741,13 +2216,28 @@ mod tests { voting_period, init_funds, false, + None, + None, ); // create proposal let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER5); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER5), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1778,4 +2268,490 @@ mod tests { .unwrap(); assert_eq!(prop_status(&app), Status::Passed); } + + #[test] + fn test_instantiate_with_invalid_deposit() { + let mut app = App::default(); + + let flex_id = app.store_code(contract_flex()); + + let group_addr = instantiate_group( + &mut app, + vec![Member { + addr: OWNER.to_string(), + weight: 10, + }], + ); + + // Instantiate with an invalid cw20 token. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::new(1), + refund_failed_proposals: true, + denom: UncheckedDenom::Cw20(group_addr.to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::InvalidCw20 {})); + + // Instantiate with a zero amount. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::zero(), + refund_failed_proposals: true, + denom: UncheckedDenom::Native("native".to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::ZeroDeposit {})) + } + + #[test] + fn test_cw20_proposal_deposit() { + let mut app = App::default(); + + let cw20_id = app.store_code(contract_cw20()); + + let cw20_addr = app + .instantiate_contract( + cw20_id, + Addr::unchecked(OWNER), + &cw20_base::msg::InstantiateMsg { + name: "Token".to_string(), + symbol: "TOKEN".to_string(), + decimals: 6, + initial_balances: vec![ + Cw20Coin { + address: VOTER4.to_string(), + amount: Uint128::new(10), + }, + Cw20Coin { + address: BANDWIDTH_CONTRACT.to_string(), + amount: Uint128::new(10), + }, + Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(10), + }, + ], + mint: None, + marketing: None, + }, + &[], + "Token", + None, + ) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Cw20(cw20_addr.to_string()), + refund_failed_proposals: true, + }), + ); + + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that will pass. + let proposal = text_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); + + // Make sure the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: BANDWIDTH_CONTRACT.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Check that the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr, + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + } + + #[test] + fn proposal_deposit_no_failed_refunds() { + let mut app = App::default(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: false, + }), + ); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: BANDWIDTH_CONTRACT.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + // Check that the deposit was transfered. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 1, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Check that the deposit wasn't returned. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + } + + #[test] + fn test_native_proposal_deposit() { + let mut app = App::default(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: VOTER4.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: BANDWIDTH_CONTRACT.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: true, + }), + ); + + // Make a proposal that will pass. + let proposal = text_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); + + // Make sure the deposit was transfered. + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance = app.wrap().query_balance(VOTER4, "TOKEN").unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance = app + .wrap() + .query_balance(BANDWIDTH_CONTRACT, "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + } } diff --git a/contracts/multisig/cw3-flex-multisig/src/lib.rs b/contracts/multisig/cw3-flex-multisig/src/lib.rs index 3407c199dd..bc3020f956 100644 --- a/contracts/multisig/cw3-flex-multisig/src/lib.rs +++ b/contracts/multisig/cw3-flex-multisig/src/lib.rs @@ -1,2 +1,25 @@ +/*! +This builds on [`cw3_fixed_multisig`] with a more +powerful implementation of the [cw3 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). +It is a multisig contract that is backed by a +[cw4 (group)](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md) contract, which independently +maintains the voter set. + +This provides 2 main advantages: + +* You can create two different multisigs with different voting thresholds + backed by the same group. Thus, you can have a 50% vote, and a 67% vote + that always use the same voter set, but can take other actions. +* TODO: It allows dynamic multisig groups. + + +In addition to the dynamic voting set, the main difference with the native +Cosmos SDK multisig, is that it aggregates the signatures on chain, with +visible proposals (like `x/gov` in the Cosmos SDK), rather than requiring +signers to share signatures off chain. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-flex-multisig/README.md). + */ + pub mod contract; -pub mod state; diff --git a/contracts/multisig/cw3-flex-multisig/src/state.rs b/contracts/multisig/cw3-flex-multisig/src/state.rs deleted file mode 100644 index 0826f1014e..0000000000 --- a/contracts/multisig/cw3-flex-multisig/src/state.rs +++ /dev/null @@ -1,20 +0,0 @@ -use cosmwasm_std::Addr; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cw4::Cw4Contract; -use cw_storage_plus::Item; -use cw_utils::{Duration, Threshold}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Config { - pub threshold: Threshold, - pub max_voting_period: Duration, - // Total weight and voters are queried from this contract - pub group_addr: Cw4Contract, - pub coconut_bandwidth_addr: Addr, - pub coconut_dkg_addr: Addr, -} - -// unique items -pub const CONFIG: Item = Item::new("config"); diff --git a/contracts/multisig/cw4-group/.cargo/config b/contracts/multisig/cw4-group/.cargo/config index 7d1a066c82..4c5472df3b 100644 --- a/contracts/multisig/cw4-group/.cargo/config +++ b/contracts/multisig/cw4-group/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema" \ No newline at end of file diff --git a/contracts/multisig/cw4-group/Cargo.toml b/contracts/multisig/cw4-group/Cargo.toml index 4605ec5bcc..180ee66b9d 100644 --- a/contracts/multisig/cw4-group/Cargo.toml +++ b/contracts/multisig/cw4-group/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "cw4-group" -version = "0.13.4" +version = "1.0.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" @@ -20,6 +20,8 @@ exclude = [ 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 = [] @@ -31,10 +33,8 @@ cw2 = { workspace = true } cw4 = { workspace = true } cw-controllers = { workspace = true } cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { workspace = true } diff --git a/contracts/multisig/cw4-group/src/contract.rs b/contracts/multisig/cw4-group/src/contract.rs index c141210507..a6069f3b23 100644 --- a/contracts/multisig/cw4-group/src/contract.rs +++ b/contracts/multisig/cw4-group/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ attr, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, - SubMsg, + SubMsg, Uint64, }; use cw2::set_contract_version; use cw4::{ @@ -13,6 +13,7 @@ use cw_storage_plus::Bound; use cw_utils::maybe_addr; use crate::error::ContractError; +use crate::helpers::validate_unique_members; use crate::state::{ADMIN, HOOKS, MEMBERS, TOTAL}; use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -39,21 +40,25 @@ pub fn instantiate( pub fn create( mut deps: DepsMut, admin: Option, - members: Vec, + mut members: Vec, height: u64, ) -> Result<(), ContractError> { + validate_unique_members(&mut members)?; + let members = members; // let go of mutability + let admin_addr = admin .map(|admin| deps.api.addr_validate(&admin)) .transpose()?; ADMIN.set(deps.branch(), admin_addr)?; - let mut total = 0u64; + let mut total = Uint64::zero(); for member in members.into_iter() { - total += member.weight; + let member_weight = Uint64::from(member.weight); + total = total.checked_add(member_weight)?; let member_addr = deps.api.addr_validate(&member.addr)?; - MEMBERS.save(deps.storage, &member_addr, &member.weight, height)?; + MEMBERS.save(deps.storage, &member_addr, &member_weight.u64(), height)?; } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(()) } @@ -115,20 +120,23 @@ pub fn update_members( deps: DepsMut, height: u64, sender: Addr, - to_add: Vec, + mut to_add: Vec, to_remove: Vec, ) -> Result { + validate_unique_members(&mut to_add)?; + let to_add = to_add; // let go of mutability + ADMIN.assert_admin(deps.as_ref(), &sender)?; - let mut total = TOTAL.load(deps.storage)?; + let mut total = Uint64::from(TOTAL.load(deps.storage)?); let mut diffs: Vec = vec![]; // add all new members and update total for add in to_add.into_iter() { let add_addr = deps.api.addr_validate(&add.addr)?; MEMBERS.update(deps.storage, &add_addr, height, |old| -> StdResult<_> { - total -= old.unwrap_or_default(); - total += add.weight; + total = total.checked_sub(Uint64::from(old.unwrap_or_default()))?; + total = total.checked_add(Uint64::from(add.weight))?; diffs.push(MemberDiff::new(add.addr, old, Some(add.weight))); Ok(add.weight) })?; @@ -140,12 +148,12 @@ pub fn update_members( // Only process this if they were actually in the list before if let Some(weight) = old { diffs.push(MemberDiff::new(remove, Some(weight), None)); - total -= weight; + total = total.checked_sub(Uint64::from(weight))?; MEMBERS.remove(deps.storage, &remove_addr, height)?; } } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(MemberChangedHookMsg { diffs }) } @@ -157,20 +165,26 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { at_height: height, } => to_binary(&query_member(deps, addr, height)?), QueryMsg::ListMembers { start_after, limit } => { - to_binary(&list_members(deps, start_after, limit)?) + to_binary(&query_list_members(deps, start_after, limit)?) + } + QueryMsg::TotalWeight { at_height: height } => { + to_binary(&query_total_weight(deps, height)?) } - QueryMsg::TotalWeight {} => to_binary(&query_total_weight(deps)?), QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), QueryMsg::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?), } } -fn query_total_weight(deps: Deps) -> StdResult { - let weight = TOTAL.load(deps.storage)?; +pub fn query_total_weight(deps: Deps, height: Option) -> StdResult { + let weight = match height { + Some(h) => TOTAL.may_load_at_height(deps.storage, h), + None => TOTAL.may_load(deps.storage), + }? + .unwrap_or_default(); Ok(TotalWeightResponse { weight }) } -fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { +pub fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { let addr = deps.api.addr_validate(&addr)?; let weight = match height { Some(h) => MEMBERS.may_load_at_height(deps.storage, &addr, h), @@ -183,7 +197,7 @@ fn query_member(deps: Deps, addr: String, height: Option) -> StdResult, limit: Option, @@ -205,352 +219,3 @@ fn list_members( Ok(MemberListResponse { members }) } - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_slice, Api, OwnedDeps, Querier, Storage}; - use cw4::{member_key, TOTAL_KEY}; - use cw_controllers::{AdminError, HookError}; - - const INIT_ADMIN: &str = "juan"; - const USER1: &str = "somebody"; - const USER2: &str = "else"; - const USER3: &str = "funny"; - - fn do_instantiate(deps: DepsMut) { - let msg = InstantiateMsg { - admin: Some(INIT_ADMIN.into()), - members: vec![ - Member { - addr: USER1.into(), - weight: 11, - }, - Member { - addr: USER2.into(), - weight: 6, - }, - ], - }; - let info = mock_info("creator", &[]); - instantiate(deps, mock_env(), info, msg).unwrap(); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // it worked, let's query the state - let res = ADMIN.query_admin(deps.as_ref()).unwrap(); - assert_eq!(Some(INIT_ADMIN.into()), res.admin); - - let res = query_total_weight(deps.as_ref()).unwrap(); - assert_eq!(17, res.weight); - } - - #[test] - fn try_member_queries() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); - assert_eq!(member1.weight, Some(11)); - - let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); - assert_eq!(member2.weight, Some(6)); - - let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); - assert_eq!(member3.weight, None); - - let members = list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(members.members.len(), 2); - // TODO: assert the set is proper - } - - fn assert_users( - deps: &OwnedDeps, - user1_weight: Option, - user2_weight: Option, - user3_weight: Option, - height: Option, - ) { - let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); - assert_eq!(member1.weight, user1_weight); - - let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); - assert_eq!(member2.weight, user2_weight); - - let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); - assert_eq!(member3.weight, user3_weight); - - // this is only valid if we are not doing a historical query - if height.is_none() { - // compute expected metrics - let weights = [user1_weight, user2_weight, user3_weight]; - let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); - let count = weights.iter().filter(|x| x.is_some()).count(); - - // TODO: more detailed compare? - let members = list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(count, members.members.len()); - - let total = query_total_weight(deps.as_ref()).unwrap(); - assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 - } - } - - #[test] - fn add_new_remove_old_member() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER3.into(), - weight: 15, - }]; - let remove = vec![USER1.into()]; - - // non-admin cannot update - let height = mock_env().block.height; - let err = update_members( - deps.as_mut(), - height + 5, - Addr::unchecked(USER1), - add.clone(), - remove.clone(), - ) - .unwrap_err(); - assert_eq!(err, AdminError::NotAdmin {}.into()); - - // Test the values from instantiate - assert_users(&deps, Some(11), Some(6), None, None); - // Note all values were set at height, the beginning of that block was all None - assert_users(&deps, None, None, None, Some(height)); - // This will get us the values at the start of the block after instantiate (expected initial values) - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - - // admin updates properly - update_members( - deps.as_mut(), - height + 10, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - - // updated properly - assert_users(&deps, None, Some(6), Some(15), None); - - // snapshot still shows old value - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - } - - #[test] - fn add_old_remove_new_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER1.into(), - weight: 4, - }]; - let remove = vec![USER3.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, Some(4), Some(6), None, None); - } - - #[test] - fn add_and_remove_same_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER1.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, None, Some(6), Some(5), None); - } - - #[test] - fn add_remove_hooks() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - - // non-admin cannot add hook - let user_info = mock_info(USER1, &[]); - let err = execute( - deps.as_mut(), - mock_env(), - user_info.clone(), - add_msg.clone(), - ) - .unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // admin can add it, and it appears in the query - let admin_info = mock_info(INIT_ADMIN, &[]); - let _ = execute( - deps.as_mut(), - mock_env(), - admin_info.clone(), - add_msg.clone(), - ) - .unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone()]); - - // cannot remove a non-registered contract - let remove_msg = ExecuteMsg::RemoveHook { - addr: contract2.clone(), - }; - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); - assert_eq!(err, HookError::HookNotRegistered {}.into()); - - // add second contract - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); - - // cannot re-add an existing contract - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); - assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); - - // non-admin cannot remove - let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; - let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // remove the original - let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract2]); - } - - #[test] - fn hooks_fire() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - // register 2 hooks - let admin_info = mock_info(INIT_ADMIN, &[]); - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - for msg in [add_msg, add_msg2] { - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); - } - - // make some changes - add 3, remove 2, and update 1 - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER2.into()]; - let msg = ExecuteMsg::UpdateMembers { remove, add }; - - // admin updates properly - assert_users(&deps, Some(11), Some(6), None, None); - let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); - assert_users(&deps, Some(20), None, Some(5), None); - - // ensure 2 messages for the 2 hooks - assert_eq!(res.messages.len(), 2); - // same order as in the message (adds first, then remove) - let diffs = vec![ - MemberDiff::new(USER1, Some(11), Some(20)), - MemberDiff::new(USER3, None, Some(5)), - MemberDiff::new(USER2, Some(6), None), - ]; - let hook_msg = MemberChangedHookMsg { diffs }; - let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); - let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); - assert_eq!(res.messages, vec![msg1, msg2]); - } - - #[test] - fn raw_queries_work() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // get total from raw key - let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); - let total: u64 = from_slice(&total_raw).unwrap(); - assert_eq!(17, total); - - // get member votes from raw key - let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); - let member2: u64 = from_slice(&member2_raw).unwrap(); - assert_eq!(6, member2); - - // and execute misses - let member3_raw = deps.storage.get(&member_key(USER3)); - assert_eq!(None, member3_raw); - } -} diff --git a/contracts/multisig/cw4-group/src/error.rs b/contracts/multisig/cw4-group/src/error.rs index 8c88fb2255..bd5acb30fb 100644 --- a/contracts/multisig/cw4-group/src/error.rs +++ b/contracts/multisig/cw4-group/src/error.rs @@ -1,19 +1,25 @@ -use cosmwasm_std::StdError; +use cosmwasm_std::{OverflowError, StdError}; use thiserror::Error; use cw_controllers::{AdminError, HookError}; #[derive(Error, Debug, PartialEq)] pub enum ContractError { - #[error(transparent)] + #[error("{0}")] Std(#[from] StdError), - #[error(transparent)] + #[error("{0}")] Hook(#[from] HookError), - #[error(transparent)] + #[error("{0}")] Admin(#[from] AdminError), + #[error("{0}")] + Overflow(#[from] OverflowError), + #[error("Unauthorized")] Unauthorized {}, + + #[error("Message contained duplicate member: {member}")] + DuplicateMember { member: String }, } diff --git a/contracts/multisig/cw4-group/src/helpers.rs b/contracts/multisig/cw4-group/src/helpers.rs index eae8a2434e..c6b5d0187c 100644 --- a/contracts/multisig/cw4-group/src/helpers.rs +++ b/contracts/multisig/cw4-group/src/helpers.rs @@ -1,17 +1,17 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::ops::Deref; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use cw4::{Cw4Contract, Member}; +use crate::ContractError; use nym_group_contract_common::msg::ExecuteMsg; /// Cw4GroupContract is a wrapper around Cw4Contract that provides a lot of helpers /// for working with cw4-group contracts. /// /// It extends Cw4Contract to add the extra calls from cw4-group. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw4GroupContract(pub Cw4Contract); impl Deref for Cw4GroupContract { @@ -41,3 +41,17 @@ impl Cw4GroupContract { self.encode_msg(msg) } } + +/// Sorts the slice and verifies all member addresses are unique. +pub fn validate_unique_members(members: &mut [Member]) -> Result<(), ContractError> { + members.sort_by(|a, b| a.addr.cmp(&b.addr)); + for (a, b) in members.iter().zip(members.iter().skip(1)) { + if a.addr == b.addr { + return Err(ContractError::DuplicateMember { + member: a.addr.clone(), + }); + } + } + + Ok(()) +} diff --git a/contracts/multisig/cw4-group/src/lib.rs b/contracts/multisig/cw4-group/src/lib.rs index 3870baf04b..06fd08f822 100644 --- a/contracts/multisig/cw4-group/src/lib.rs +++ b/contracts/multisig/cw4-group/src/lib.rs @@ -1,6 +1,25 @@ +/*! +This is a basic implementation of the [cw4 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). +It fulfills all elements of the spec, including the raw query lookups, +and it designed to be used as a backing storage for +[cw3 compliant contracts](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). + +It stores a set of members along with an admin, and allows the admin to +update the state. Raw queries (intended for cross-contract queries) +can check a given member address and the total weight. Smart queries (designed +for client API) can do the same, and also query the admin address as well as +paginate over all members. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw4-group/README.md). + */ + pub mod contract; pub mod error; pub mod helpers; pub mod state; pub use crate::error::ContractError; + +#[cfg(test)] +mod tests; diff --git a/contracts/multisig/cw4-group/src/state.rs b/contracts/multisig/cw4-group/src/state.rs index 1b5003c985..10497fa99d 100644 --- a/contracts/multisig/cw4-group/src/state.rs +++ b/contracts/multisig/cw4-group/src/state.rs @@ -1,16 +1,24 @@ use cosmwasm_std::Addr; -use cw4::TOTAL_KEY; +use cw4::{ + MEMBERS_CHANGELOG, MEMBERS_CHECKPOINTS, MEMBERS_KEY, TOTAL_KEY, TOTAL_KEY_CHANGELOG, + TOTAL_KEY_CHECKPOINTS, +}; use cw_controllers::{Admin, Hooks}; -use cw_storage_plus::{Item, SnapshotMap, Strategy}; +use cw_storage_plus::{SnapshotItem, SnapshotMap, Strategy}; pub const ADMIN: Admin = Admin::new("admin"); pub const HOOKS: Hooks = Hooks::new("cw4-hooks"); -pub const TOTAL: Item = Item::new(TOTAL_KEY); - -pub const MEMBERS: SnapshotMap<&Addr, u64> = SnapshotMap::new( - cw4::MEMBERS_KEY, - cw4::MEMBERS_CHECKPOINTS, - cw4::MEMBERS_CHANGELOG, +pub const TOTAL: SnapshotItem = SnapshotItem::new( + TOTAL_KEY, + TOTAL_KEY_CHECKPOINTS, + TOTAL_KEY_CHANGELOG, + Strategy::EveryBlock, +); + +pub const MEMBERS: SnapshotMap<&Addr, u64> = SnapshotMap::new( + MEMBERS_KEY, + MEMBERS_CHECKPOINTS, + MEMBERS_CHANGELOG, Strategy::EveryBlock, ); diff --git a/contracts/multisig/cw4-group/src/tests.rs b/contracts/multisig/cw4-group/src/tests.rs new file mode 100644 index 0000000000..11f39f7084 --- /dev/null +++ b/contracts/multisig/cw4-group/src/tests.rs @@ -0,0 +1,439 @@ +use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::{from_slice, Addr, Api, DepsMut, OwnedDeps, Querier, Storage, SubMsg}; +use cw4::{member_key, Member, MemberChangedHookMsg, MemberDiff, TOTAL_KEY}; +use cw_controllers::{AdminError, HookError}; + +use crate::contract::{ + execute, instantiate, query_list_members, query_member, query_total_weight, update_members, +}; +use crate::state::{ADMIN, HOOKS}; +use crate::ContractError; +use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg}; + +const INIT_ADMIN: &str = "juan"; +const USER1: &str = "somebody"; +const USER2: &str = "else"; +const USER3: &str = "funny"; + +fn set_up(deps: DepsMut) { + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ + Member { + addr: USER1.into(), + weight: 11, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + ], + }; + let info = mock_info("creator", &[]); + instantiate(deps, mock_env(), info, msg).unwrap(); +} + +#[test] +fn proper_instantiation() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // it worked, let's query the state + let res = ADMIN.query_admin(deps.as_ref()).unwrap(); + assert_eq!(Some(INIT_ADMIN.into()), res.admin); + + let res = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, res.weight); +} + +#[test] +fn try_member_queries() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); + assert_eq!(member1.weight, Some(11)); + + let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); + assert_eq!(member2.weight, Some(6)); + + let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); + assert_eq!(member3.weight, None); + + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(members.members.len(), 2); + // TODO: assert the set is proper +} + +#[test] +fn duplicate_members_instantiation() { + let mut deps = mock_dependencies(); + + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ + Member { + addr: USER1.into(), + weight: 5, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + Member { + addr: USER1.into(), + weight: 6, + }, + ], + }; + let info = mock_info("creator", &[]); + let err = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::DuplicateMember { + member: USER1.to_string() + } + ); +} + +#[test] +fn duplicate_members_execution() { + let mut deps = mock_dependencies(); + + set_up(deps.as_mut()); + + let add = vec![ + Member { + addr: USER3.into(), + weight: 15, + }, + Member { + addr: USER3.into(), + weight: 11, + }, + ]; + + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(INIT_ADMIN), + add, + vec![], + ) + .unwrap_err(); + + assert_eq!( + err, + ContractError::DuplicateMember { + member: USER3.to_string() + } + ); +} + +fn assert_users( + deps: &OwnedDeps, + user1_weight: Option, + user2_weight: Option, + user3_weight: Option, + height: Option, +) { + let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); + assert_eq!(member1.weight, user1_weight); + + let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); + assert_eq!(member2.weight, user2_weight); + + let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); + assert_eq!(member3.weight, user3_weight); + + // this is only valid if we are not doing a historical query + if height.is_none() { + // compute expected metrics + let weights = [user1_weight, user2_weight, user3_weight]; + let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); + let count = weights.iter().filter(|x| x.is_some()).count(); + + // TODO: more detailed compare? + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(count, members.members.len()); + + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 + } +} + +#[test] +fn add_new_remove_old_member() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER3.into(), + weight: 15, + }]; + let remove = vec![USER1.into()]; + + // non-admin cannot update + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(USER1), + add.clone(), + remove.clone(), + ) + .unwrap_err(); + assert_eq!(err, AdminError::NotAdmin {}.into()); + + // Test the values from instantiate + assert_users(&deps, Some(11), Some(6), None, None); + // Note all values were set at height, the beginning of that block was all None + assert_users(&deps, None, None, None, Some(height)); + // This will get us the values at the start of the block after instantiate (expected initial values) + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); + + // admin updates properly + update_members( + deps.as_mut(), + height + 10, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + + // updated properly + assert_users(&deps, None, Some(6), Some(15), None); + + // snapshot still shows old value + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); +} + +#[test] +fn add_old_remove_new_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER1.into(), + weight: 4, + }]; + let remove = vec![USER3.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, Some(4), Some(6), None, None); +} + +#[test] +fn add_and_remove_same_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER1.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, None, Some(6), Some(5), None); +} + +#[test] +fn add_remove_hooks() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + + // non-admin cannot add hook + let user_info = mock_info(USER1, &[]); + let err = execute( + deps.as_mut(), + mock_env(), + user_info.clone(), + add_msg.clone(), + ) + .unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // admin can add it, and it appears in the query + let admin_info = mock_info(INIT_ADMIN, &[]); + let _ = execute( + deps.as_mut(), + mock_env(), + admin_info.clone(), + add_msg.clone(), + ) + .unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone()]); + + // cannot remove a non-registered contract + let remove_msg = ExecuteMsg::RemoveHook { + addr: contract2.clone(), + }; + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); + assert_eq!(err, HookError::HookNotRegistered {}.into()); + + // add second contract + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); + + // cannot re-add an existing contract + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); + assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); + + // non-admin cannot remove + let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; + let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // remove the original + let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract2]); +} + +#[test] +fn hooks_fire() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + // register 2 hooks + let admin_info = mock_info(INIT_ADMIN, &[]); + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + for msg in [add_msg, add_msg2] { + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); + } + + // make some changes - add 3, remove 2, and update 1 + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER2.into()]; + let msg = ExecuteMsg::UpdateMembers { remove, add }; + + // admin updates properly + assert_users(&deps, Some(11), Some(6), None, None); + let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); + assert_users(&deps, Some(20), None, Some(5), None); + + // ensure 2 messages for the 2 hooks + assert_eq!(res.messages.len(), 2); + // same order as in the message (adds first, then remove) + // order of added users is not guaranteed to be preserved + let diffs = vec![ + MemberDiff::new(USER3, None, Some(5)), + MemberDiff::new(USER1, Some(11), Some(20)), + MemberDiff::new(USER2, Some(6), None), + ]; + let hook_msg = MemberChangedHookMsg { diffs }; + let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); + let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); + dbg!(&res.messages); + dbg!(&msg1); + dbg!(&msg2); + assert_eq!(res.messages, vec![msg1, msg2]); +} + +#[test] +fn raw_queries_work() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // get total from raw key + let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); + let total: u64 = from_slice(&total_raw).unwrap(); + assert_eq!(17, total); + + // get member votes from raw key + let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); + let member2: u64 = from_slice(&member2_raw).unwrap(); + assert_eq!(6, member2); + + // and execute misses + let member3_raw = deps.storage.get(&member_key(USER3)); + assert_eq!(None, member3_raw); +} + +#[test] +fn total_at_height() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let height = mock_env().block.height; + + // Test the values from instantiate + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, total.weight); + // Note all values were set at height, the beginning of that block was all None + let total = query_total_weight(deps.as_ref(), Some(height)).unwrap(); + assert_eq!(0, total.weight); + // This will get us the values at the start of the block after instantiate (expected initial values) + let total = query_total_weight(deps.as_ref(), Some(height + 1)).unwrap(); + assert_eq!(17, total.weight); +} diff --git a/contracts/name-service/src/state/names.rs b/contracts/name-service/src/state/names.rs index 27af9f3407..3b2b02f82d 100644 --- a/contracts/name-service/src/state/names.rs +++ b/contracts/name-service/src/state/names.rs @@ -30,12 +30,12 @@ fn names<'a>() -> IndexedMap<'a, NameId, RegisteredName, NameIndex<'a>> { let indexes = NameIndex { name: UniqueIndex::new(|d| d.name.name.to_string(), NAMES_NAME_IDX_NAMESPACE), address: MultiIndex::new( - |d| d.name.address.to_string(), + |_pk, d| d.name.address.to_string(), NAMES_PK_NAMESPACE, NAMES_ADDRESS_IDX_NAMESPACE, ), owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), NAMES_PK_NAMESPACE, NAMES_OWNER_IDX_NAMESPACE, ), diff --git a/contracts/service-provider-directory/src/state/services.rs b/contracts/service-provider-directory/src/state/services.rs index 54b9c27bcf..e5e68a21ff 100644 --- a/contracts/service-provider-directory/src/state/services.rs +++ b/contracts/service-provider-directory/src/state/services.rs @@ -26,12 +26,12 @@ impl<'a> IndexList for ServiceIndex<'a> { fn services<'a>() -> IndexedMap<'a, ServiceId, Service, ServiceIndex<'a>> { let indexes = ServiceIndex { nym_address: MultiIndex::new( - |d| d.service.nym_address.to_string(), + |_pk, d| d.service.nym_address.to_string(), SERVICES_PK_NAMESPACE, SERVICES_NYM_ADDRESS_IDX_NAMESPACE, ), announcer: MultiIndex::new( - |d| d.announcer.clone(), + |_pk, d| d.announcer.clone(), SERVICES_PK_NAMESPACE, SERVICES_ANNOUNCER_IDX_NAMESPACE, ), diff --git a/contracts/vesting/src/vesting/account/mod.rs b/contracts/vesting/src/vesting/account/mod.rs index 1e0aa25348..e59f27d1a2 100644 --- a/contracts/vesting/src/vesting/account/mod.rs +++ b/contracts/vesting/src/vesting/account/mod.rs @@ -25,7 +25,7 @@ fn generate_storage_key(storage: &mut dyn Storage) -> Result, diff --git a/explorer-api/src/mix_node/models.rs b/explorer-api/src/mix_node/models.rs index 462d41c3b5..94ae6558d0 100644 --- a/explorer-api/src/mix_node/models.rs +++ b/explorer-api/src/mix_node/models.rs @@ -45,7 +45,7 @@ pub(crate) struct PrettyDetailedMixNodeBond { pub blacklisted: bool, } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct SummedDelegations { pub owner: Addr, pub mix_id: MixId, diff --git a/integrations/bity/Cargo.toml b/integrations/bity/Cargo.toml index 8bab2b3e77..4ae51337c9 100644 --- a/integrations/bity/Cargo.toml +++ b/integrations/bity/Cargo.toml @@ -8,10 +8,10 @@ rust-version = "1.56" serde = { version = "1", features = ["derive"] } serde_json = "1" thiserror = "1.0" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { workspace = true, features = ["ecdsa", "sha256"] } eyre = "0.6.5" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } nym-cli-commands = { path = "../../common/commands" } nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index ed8dc1dce6..37aded5efa 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bs58 = "0.4.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } cosmwasm-std = { workspace = true, default-features = false } getset = "0.1.1" schemars = { version = "0.8", features = ["preserve_order"] } diff --git a/nym-api/src/coconut/tests.rs b/nym-api/src/coconut/tests.rs index 7ebf4908a7..0648e9c8ca 100644 --- a/nym-api/src/coconut/tests.rs +++ b/nym-api/src/coconut/tests.rs @@ -443,6 +443,8 @@ impl super::client::Client for DummyClient { percentage: Decimal::from_ratio(2u32, 3u32), total_weight: 100, }, + proposer: Addr::unchecked(self.validator_address.as_ref()), + deposit: None, }; self.proposal_db .write() @@ -904,6 +906,8 @@ async fn verification_of_bandwidth_credential() { percentage: Decimal::from_ratio(2u32, 3u32), total_weight: 100, }, + proposer: Addr::unchecked("proposer"), + deposit: None, }; // Test the endpoint with a different blinded serial number in the description diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 0cb8b27caf..4b515a4f54 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -228,18 +228,18 @@ dependencies = [ [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -326,7 +326,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -339,12 +338,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -707,9 +700,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" @@ -766,8 +759,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -776,8 +770,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -798,11 +793,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -811,26 +806,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -944,9 +966,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1064,10 +1086,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1078,9 +1101,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1089,22 +1112,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1112,11 +1139,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1124,11 +1152,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1196,11 +1240,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1354,9 +1410,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1410,16 +1466,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1550,6 +1608,16 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.5" @@ -2071,6 +2139,17 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "gtk" version = "0.15.5" @@ -2702,23 +2781,22 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -3524,6 +3602,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3540,7 +3620,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -3550,7 +3630,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -4200,11 +4282,11 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -4427,13 +4509,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -4833,12 +4914,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -4881,6 +4962,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -5091,10 +5181,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -5190,6 +5281,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -5368,14 +5468,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -5398,11 +5496,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -5506,9 +5604,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -6150,9 +6248,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -6181,9 +6279,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -6195,9 +6293,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -6213,9 +6311,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index fa2722e281..14bc9eb0e6 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -122,9 +122,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" @@ -220,18 +220,18 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", "arrayvec", @@ -321,7 +321,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -334,20 +333,14 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.6.0" source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278" dependencies = [ "digest 0.9.0", - "ff", - "group", + "ff 0.11.1", + "group 0.11.0", "pairing", "rand_core 0.6.4", "subtle 2.4.1", @@ -688,15 +681,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "convert_case" @@ -747,8 +740,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -757,8 +751,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -779,11 +774,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -792,26 +787,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.107", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -857,14 +879,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] @@ -885,9 +907,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1011,10 +1033,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1025,9 +1048,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1036,22 +1059,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.16", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1059,11 +1086,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1071,11 +1099,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1119,11 +1163,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", ] [[package]] @@ -1271,9 +1327,9 @@ checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1327,16 +1383,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1451,6 +1509,16 @@ dependencies = [ "subtle 2.4.1", ] +[[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 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.4" @@ -1921,7 +1989,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ "byteorder", - "ff", + "ff 0.11.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[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 2.4.1", ] @@ -2106,7 +2185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest 0.9.0", - "hmac", + "hmac 0.11.0", ] [[package]] @@ -2119,6 +2198,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -2496,23 +2584,22 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -2700,9 +2787,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -2935,9 +3022,9 @@ dependencies = [ "bls12_381", "bs58", "digest 0.9.0", - "ff", + "ff 0.11.1", "getrandom 0.2.10", - "group", + "group 0.11.0", "itertools", "nym-dkg", "nym-pemstore", @@ -3027,8 +3114,8 @@ dependencies = [ "bitvec", "bls12_381", "bs58", - "ff", - "group", + "ff 0.11.1", + "group 0.11.0", "lazy_static", "nym-pemstore", "rand 0.8.5", @@ -3045,6 +3132,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3061,7 +3150,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -3072,7 +3161,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -3499,7 +3590,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42" dependencies = [ - "group", + "group 0.11.0", ] [[package]] @@ -3575,11 +3666,11 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -3802,13 +3893,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -4222,12 +4312,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -4270,6 +4360,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -4423,10 +4522,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -4522,6 +4622,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -4687,14 +4796,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -4717,11 +4824,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -4799,7 +4906,7 @@ dependencies = [ "curve25519-dalek", "digest 0.9.0", "hkdf", - "hmac", + "hmac 0.11.0", "lioness", "log", "rand 0.7.3", @@ -4816,9 +4923,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -5236,9 +5343,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -5267,9 +5374,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -5281,9 +5388,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -5299,9 +5406,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/nym-wallet/Cargo.toml b/nym-wallet/Cargo.toml index 80e269fba7..de5e6faf93 100644 --- a/nym-wallet/Cargo.toml +++ b/nym-wallet/Cargo.toml @@ -5,4 +5,4 @@ members = [ "src-tauri", "nym-wallet-recovery-cli", "nym-wallet-types" -] +] \ No newline at end of file diff --git a/nym-wallet/nym-wallet-types/Cargo.toml b/nym-wallet/nym-wallet-types/Cargo.toml index 8d47e3d70d..99d0ef784b 100644 --- a/nym-wallet/nym-wallet-types/Cargo.toml +++ b/nym-wallet/nym-wallet-types/Cargo.toml @@ -12,7 +12,7 @@ strum = { version = "0.23", features = ["derive"] } ts-rs = "6.1.2" cosmwasm-std = "1.0.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = "=0.8.0" nym-config = { path = "../../common/config" } nym-network-defaults = { path = "../../common/network-defaults" } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 06757de614..2d65946c23 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -44,12 +44,12 @@ thiserror = "1.0" tokio = { version = "1.10", features = ["full"] } toml = "0.5.8" url = "2.2" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { version = "0.11", features = ["ecdsa", "sha256"] } base64 = "0.13" zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } cosmwasm-std = "1.0.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = "=0.8.0" nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ "nyxd-client",