diff --git a/Cargo.lock b/Cargo.lock index 2d9b6ad..3bbebff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" dependencies = [ "backtrace", ] @@ -171,6 +171,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "bitflags" version = "1.3.2" @@ -213,6 +219,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" + [[package]] name = "bnum" version = "0.10.0" @@ -224,11 +236,11 @@ name = "broker-bank" version = "0.1.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus", - "cw2", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", + "nibiru-ownable", "nibiru-std", "schemars", "serde", @@ -242,12 +254,12 @@ version = "0.2.0" dependencies = [ "anyhow", "broker-bank", - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus", - "cw-utils", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw20 2.0.0", + "nibiru-ownable", "nibiru-std", "schemars", "serde", @@ -380,9 +392,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" name = "controller" version = "0.2.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", "nibiru-std", "schemars", "serde", @@ -410,11 +422,11 @@ name = "core-token-vesting-v2" version = "2.1.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw20", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20 1.1.2", "schemars", "serde", "serde_json", @@ -436,9 +448,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" dependencies = [ "digest 0.10.7", "ecdsa", @@ -448,6 +460,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cosmwasm-crypto" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b08e6670ab9e13a1a8a9cfad8fdad48bf0aaf88a6e81f39f2d9b2fc79b1890" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + [[package]] name = "cosmwasm-derive" version = "1.5.3" @@ -457,13 +482,35 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-derive" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b0918fc1a24b2ee08142c8d99d03f4c8e6d74244bdb304dbb29c0dab8e77e9" +dependencies = [ + "syn 1.0.109", +] + [[package]] name = "cosmwasm-schema" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ - "cosmwasm-schema-derive", + "cosmwasm-schema-derive 1.5.3", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dbdb5800ca67f2f2f938d67db59a7c5434af133c3e508779a4df7a9b5d533b" +dependencies = [ + "cosmwasm-schema-derive 2.0.2", "schemars", "serde", "serde_json", @@ -481,17 +528,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-schema-derive" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ee47cf29f7688ebfa6ade8ddabcf51fc153f1157a3b46f5b4b1ce7a0316fdf" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "cosmwasm-std" -version = "1.5.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" +checksum = "ad011ae7447188e26e4a7dbca2fcd0fc186aa21ae5c86df0503ea44c78f9e469" dependencies = [ "base64", - "bech32", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", + "bech32 0.9.1", + "bnum 0.8.1", + "cosmwasm-crypto 1.5.2", + "cosmwasm-derive 1.5.3", "derivative", "forward_ref", "hex", @@ -503,26 +561,49 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cosmwasm-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88191bd0d4743613eb7a2f086acb0838404cb531bf658382effafc7ba91e8320" +dependencies = [ + "base64", + "bech32 0.9.1", + "bnum 0.10.0", + "cosmwasm-crypto 2.0.2", + "cosmwasm-derive 2.0.2", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm 1.0.1", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + [[package]] name = "cosmwasm-vm" -version = "1.5.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011bc44b0d617f440ea509b38e543437511a196c6e2a0ebd3425edd912902fb2" +checksum = "184841233ccfac1b1826821a24bdd7d75228c07cb493c1b8c265ef2482950a58" dependencies = [ + "bech32 0.9.1", "bitflags 1.3.2", "bytecheck", "bytes", "clru", - "cosmwasm-crypto", - "cosmwasm-std", + "cosmwasm-crypto 2.0.2", + "cosmwasm-std 2.0.2", "crc32fast", "derivative", - "enumset", "hex", "schemars", "serde", "serde_json", "sha2 0.10.8", + "strum", "thiserror", "wasmer", "wasmer-middlewares", @@ -700,23 +781,21 @@ dependencies = [ [[package]] name = "cw-address-like" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +version = "2.0.0" dependencies = [ - "cosmwasm-std", + "cosmwasm-std 2.0.2", ] [[package]] name = "cw-controllers" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" +checksum = "50c1804013d21060b994dea28a080f9eab78a3bcb6b617f05e7634b0600bf7b1" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", "schemars", "serde", "thiserror", @@ -724,16 +803,17 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.17.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d818f5323c80ed4890db7f89d65eda3f0261fe21878e628c27ea2d8de4b7ba4" +checksum = "e403ad6ec62c8bcbcb75f7f4940712d0142b6103310da2a9375252b942358caa" dependencies = [ "anyhow", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", + "bech32 0.11.0", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", "derivative", - "itertools 0.11.0", + "itertools", "prost", "schemars", "serde", @@ -742,71 +822,64 @@ dependencies = [ ] [[package]] -name = "cw-multi-test" -version = "0.20.0" +name = "cw-storage-plus" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ - "anyhow", - "bech32", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools 0.12.1", - "prost", + "cosmwasm-std 1.5.2", "schemars", "serde", - "sha2 0.10.8", - "thiserror", ] [[package]] -name = "cw-ownable" -version = "0.5.1" +name = "cw-storage-plus" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +checksum = "f13360e9007f51998d42b1bc6b7fa0141f74feae61ed5fd1e5b0a89eec7b5de1" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus", - "cw-utils", - "thiserror", + "cosmwasm-std 2.0.2", + "schemars", + "serde", ] [[package]] -name = "cw-ownable-derive" -version = "0.5.1" +name = "cw-utils" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw2 1.1.2", + "schemars", + "semver", + "serde", + "thiserror", ] [[package]] -name = "cw-storage-plus" -version = "1.2.0" +name = "cw-utils" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" +checksum = "07dfee7f12f802431a856984a32bce1cb7da1e6c006b5409e3981035ce562dec" dependencies = [ - "cosmwasm-std", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", "schemars", "serde", + "thiserror", ] [[package]] -name = "cw-utils" -version = "1.0.3" +name = "cw2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw-storage-plus 1.2.0", "schemars", "semver", "serde", @@ -815,13 +888,13 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" +checksum = "b04852cd38f044c0751259d5f78255d07590d136b8a86d4e09efdd7666bd6d27" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", "schemars", "semver", "serde", @@ -834,24 +907,37 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw20" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a42212b6bf29bbdda693743697c621894723f35d3db0d5df930be22903d0e27c" +dependencies = [ + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-utils 2.0.0", "schemars", "serde", ] [[package]] name = "cw20-base" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" +checksum = "d6de8c32e100f1fca306972d86b617234a5e6b00594ea2b48716fd6804d4d95d" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw2", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", + "cw20 2.0.0", "schemars", "semver", "serde", @@ -860,14 +946,14 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" +checksum = "d5e53c2057526c65d9c88be8b2a564729ebad7a3d87ee97b97665a71446f913a" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-utils 2.0.0", + "cw20 2.0.0", "schemars", "serde", "thiserror", @@ -875,15 +961,15 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58d7480e78644625c38bb082bfe9a27b01ca58bfcb785690ef43363fd40acf51" +checksum = "9a8233125653e61e898eaade6c6fdb3bd9c48aceb2ad97e84eada2c9bf5bff46" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", "cw3", "schemars", "serde", @@ -894,18 +980,19 @@ dependencies = [ name = "cw3-flex-multisig" version = "1.0.1" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test 0.17.0", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-multi-test", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", + "cw20 2.0.0", "cw20-base", "cw3", "cw3-fixed-multisig", "cw4", "cw4-group", + "easy-addr", "schemars", "serde", "thiserror", @@ -913,29 +1000,29 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" +checksum = "d33f5c8a6b6cd1bd24e212d7f44967697bfa3c4f9cc3f9a8e1c58f5fe5db032d" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", "schemars", "serde", ] [[package]] name = "cw4-group" -version = "1.1.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" +checksum = "e60083d0aec9f6d6191c797bb3605835289fd3d875fe516ae5a164c7f8a0ba4e" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", "cw-controllers", - "cw-storage-plus", - "cw-utils", - "cw2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", "cw4", "schemars", "serde", @@ -1075,6 +1162,16 @@ dependencies = [ "memmap2 0.5.10", ] +[[package]] +name = "easy-addr" +version = "0.1.0" +dependencies = [ + "cosmwasm-std 2.0.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ecdsa" version = "0.16.9" @@ -1521,14 +1618,17 @@ dependencies = [ name = "incentives" version = "0.2.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test 0.20.0", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", + "anyhow", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-multi-test", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", + "cw20 2.0.0", + "easy-addr", "lockup", + "nibiru-std", "schemars", "serde", "serde-json-wasm 1.0.1", @@ -1561,15 +1661,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -1596,9 +1687,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -1646,12 +1737,12 @@ dependencies = [ name = "lockup" version = "0.2.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", + "cw20 2.0.0", "schemars", "serde", "thiserror", @@ -1698,9 +1789,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -1774,12 +1865,12 @@ name = "nibi-stargate" version = "0.2.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", + "cw20 2.0.0", "nibiru-std", "schemars", "serde", @@ -1791,12 +1882,13 @@ name = "nibi-stargate-perp" version = "0.2.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", + "broker-bank", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", "cosmwasm-vm", - "cw-storage-plus", - "cw-utils", - "cw2", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "cw2 2.0.0", "nibiru-std", "schemars", "serde", @@ -1804,13 +1896,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nibiru-ownable" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-address-like", + "cw-storage-plus 2.0.0", + "cw-utils 2.0.0", + "ownable-derive", + "thiserror", +] + [[package]] name = "nibiru-std" -version = "0.0.5" +version = "0.1.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", "prost", "prost-types", "serde", @@ -1823,11 +1928,11 @@ name = "nusd-valuator" version = "0.1.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus", - "cw2", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", + "nibiru-ownable", "nibiru-std", "schemars", "serde", @@ -1900,6 +2005,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ownable-derive" +version = "0.6.0" +dependencies = [ + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "nibiru-ownable", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "parking_lot_core" version = "0.9.9" @@ -1978,12 +2095,12 @@ dependencies = [ name = "pricefeed" version = "0.2.0" dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", "schemars", "serde", "thiserror", @@ -2024,9 +2141,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", "prost-derive", @@ -2034,12 +2151,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", "syn 2.0.52", @@ -2303,6 +2420,12 @@ dependencies = [ "base64", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.17" @@ -2428,9 +2551,9 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] @@ -2466,9 +2589,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", @@ -2548,11 +2671,12 @@ name = "shifter" version = "0.2.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus", - "cw2", + "cosmwasm-schema 2.0.2", + "cosmwasm-std 2.0.2", + "cw-storage-plus 2.0.0", + "cw2 2.0.0", + "easy-addr", + "nibiru-ownable", "nibiru-std", "schemars", "serde", @@ -2634,6 +2758,28 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.52", +] + [[package]] name = "subtle" version = "2.5.0" @@ -2721,18 +2867,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", @@ -2759,11 +2905,11 @@ name = "token-vesting" version = "0.2.0" dependencies = [ "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw20", + "cosmwasm-schema 1.5.3", + "cosmwasm-std 1.5.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20 1.1.2", "schemars", "serde", "serde_json", @@ -2973,29 +3119,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-downcast" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" -dependencies = [ - "js-sys", - "once_cell", - "wasm-bindgen", - "wasm-bindgen-downcast-macros", -] - -[[package]] -name = "wasm-bindgen-downcast-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "wasm-bindgen-futures" version = "0.4.42" @@ -3039,9 +3162,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasmer" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e626f958755a90a6552b9528f59b58a62ae288e6c17fcf40e99495bc33c60f0" +checksum = "5c15724dc25d1ee57962334aea8e41ade2675e5ea2ac6b8d42da6051b0face66" dependencies = [ "bytes", "cfg-if", @@ -3055,8 +3178,8 @@ dependencies = [ "shared-buffer", "target-lexicon", "thiserror", + "tracing", "wasm-bindgen", - "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", @@ -3068,9 +3191,9 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848e1922694cf97f4df680a0534c9d72c836378b5eb2313c1708fe1a75b40044" +checksum = "55a7f3b3a96f8d844c25e2c032af9572306dd63fa93dc17bcca4c5458ac569bd" dependencies = [ "backtrace", "bytes", @@ -3095,9 +3218,9 @@ dependencies = [ [[package]] name = "wasmer-compiler-cranelift" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d96bce6fad15a954edcfc2749b59e47ea7de524b6ef3df392035636491a40b4" +checksum = "102e2c5bacac69495c4025767e2fa26797ffb27f242dccb7cf57d9cefd944386" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -3114,9 +3237,9 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebaa865b40ffb3351b03dab9fe9930a5248c25daebd55b464b79b862d9b55ccd" +checksum = "2071db9b993508dac72d12f7a9372e0c095fbdc173e0009c4b75886bed4a855e" dependencies = [ "byteorder", "dynasm", @@ -3133,9 +3256,9 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f08f80d166a9279671b7af7a09409c28ede2e0b4e3acabbf0e3cb22c8038ba7" +checksum = "0ea737fa08f95d6abc4459f42a70a9833e8974b814e74971d77ef473814f4d4c" dependencies = [ "proc-macro-error", "proc-macro2", @@ -3145,9 +3268,9 @@ dependencies = [ [[package]] name = "wasmer-middlewares" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb4b87c0ea9f8636c81a8ab8f52bad01c8623c9fcbb3db5f367d5f157fada30" +checksum = "0346ed39c185c1c5c1094e6c0271d798276a34f80e1e5576bcb2e32fa2e7f05a" dependencies = [ "wasmer", "wasmer-types", @@ -3156,9 +3279,9 @@ dependencies = [ [[package]] name = "wasmer-types" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2c892882f0b416783fb4310e5697f5c30587f6f9555f9d4f2be85ab39d5d3d" +checksum = "b0689110e291b0f07fc665f2824e5ff81df120848e8a9acfbf1a9bf7990773f9" dependencies = [ "bytecheck", "enum-iterator", @@ -3172,9 +3295,9 @@ dependencies = [ [[package]] name = "wasmer-vm" -version = "4.2.2" +version = "4.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0a9a57b627fb39e5a491058d4365f099bc9b140031c000fded24a3306d9480" +checksum = "4cd41f822a1ac4242d478754e8ceba2806a00ea5072803622e1fe91e8e28b2a1" dependencies = [ "backtrace", "cc", @@ -3200,12 +3323,13 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.95.0" +version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ - "indexmap 1.9.3", - "url", + "bitflags 2.4.2", + "indexmap 2.2.5", + "semver", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 762893f..4688121 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,10 @@ members = ["scripts", "packages/*", "nibiru-std", "contracts/*"] exclude = ["packages/msig-ez"] resolver = "2" +package.version = "0.1.0" +package.homepage = "https://github.com/NibiruChain/cw-nibiru" +package.repository = "https://github.com/NibiruChain/cw-nibiru" +package.edition = "2021" # Dependencies can be inherited from a workspace by specifying the dependency in # the `[workspace.dependencies]` table. To use workspace crates, add them to the @@ -14,34 +18,38 @@ resolver = "2" serde = { version = "1.0.189", default-features = false, features = ["derive"] } serde_json = "1.0.108" +# deps: packages nibiru-std = { path = "nibiru-std" } prost = "0.12.3" prost-types = "0.12.3" -bash-rs = { path = "packages/bash-rs" } +bash-rs = { path = "packages/bash-rs" } +# Macros for controlling ownership of CosmWasm smart contracts +nibiru-ownable = { path = "packages/nibiru-ownable" } +ownable-derive = { path = "packages/nibiru-ownable/derive" } +cw-address-like = { path = "packages/cw-address-like" } +easy-addr = { path = "packages/easy-addr" } # deps: CosmWasm -cosmwasm-std = { version = "1.5.0", features = ["stargate", "staking"] } -cosmwasm-schema = "1.5.0" -cw-storage-plus = { version = "1.2.0" } -cw-multi-test = { version = "0.20.0" } -cw-utils = { version = "1.0.3" } -# Macros for controlling ownership of CosmWasm smart contracts -cw-ownable = { version = "0.5.1"} +cosmwasm-std = { version = "2.0.2", features = ["stargate", "staking"] } +cosmwasm-schema = "2.0.2" +cw-storage-plus = { version = "2.0.0" } +cw-multi-test = { version = "2.0.1" } +cw-utils = { version = "2.0.0" } # deps: cw-plus -cw2 = { version = "1.1.1" } -cw3 = { version = "1.1.1" } -cw3-fixed-multisig = { version = "1.1.1", features = ["library"] } -cw4 = { version = "1.1.1" } -cw20 = { version = "1.1.1" } +cw2 = { version = "2.0.0" } +cw3 = { version = "2.0.0" } +cw3-fixed-multisig = { version = "2.0.0", features = ["library"] } +cw4 = { version = "2.0.0" } +cw20 = { version = "2.0.0" } +cw4-group = { version = "2.0" } +cw20-base = { version = "2.0" } # deps: core contracts -# TODO: revive bindings-perp with stargate -# bindings-perp = { path = "core/core-bindings-perp" } -shifter = { path = "contracts/core-shifter" } -controller = { path = "contracts/core-controller" } -lockup = { path = "contracts/lockup", features = ["library"] } -incentives = { path = "contracts/incentives", features = ["library"] } +shifter = { path = "contracts/core-shifter" } +controller = { path = "contracts/core-controller" } +lockup = { path = "contracts/lockup", features = ["library"] } +incentives = { path = "contracts/incentives", features = ["library"] } broker-bank = { path = "contracts/broker-bank", features = ["library"] } # deps: else @@ -53,6 +61,9 @@ clap = { version = "4.4.7", features = ["derive", "cargo", "env", "string"] } schemars = "0.8.15" home = "0.5" toml = "0.8" +quote = "1.0" +syn = { version = "1", features = ["full"] } # NOTE: This needs to stay v1 +proc-macro2 = "1.0" [profile.release] opt-level = 3 diff --git a/contracts/broker-bank/.cargo/config b/contracts/broker-bank/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/broker-bank/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/core-cw3-flex-msig/.cargo/config b/contracts/broker-bank/.cargo/config.toml similarity index 50% rename from contracts/core-cw3-flex-msig/.cargo/config rename to contracts/broker-bank/.cargo/config.toml index f517478..051a969 100644 --- a/contracts/core-cw3-flex-msig/.cargo/config +++ b/contracts/broker-bank/.cargo/config.toml @@ -1,6 +1,9 @@ [alias] wasm = "build --release --lib --target wasm32-unknown-unknown" wasm-debug = "build --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/broker-bank/Cargo.toml b/contracts/broker-bank/Cargo.toml index 6f8147e..7976aa6 100644 --- a/contracts/broker-bank/Cargo.toml +++ b/contracts/broker-bank/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/NibiruChain/cw-nibiru" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # features.library: Use the library feature to disable all # instantiate/execute/query exports. This is necessary use this as a dependency # for another smart contract crate. @@ -26,5 +25,5 @@ thiserror = { workspace = true } nibiru-std = { workspace = true } cw2 = { workspace = true } serde_json = { workspace = true } -cw-ownable = { workspace = true } +nibiru-ownable = { workspace = true } anyhow = { workspace = true } \ No newline at end of file diff --git a/contracts/broker-bank/src/contract.rs b/contracts/broker-bank/src/contract.rs index 60627ba..1c823f9 100644 --- a/contracts/broker-bank/src/contract.rs +++ b/contracts/broker-bank/src/contract.rs @@ -5,6 +5,7 @@ use cosmwasm_std::{ BankQuery, Binary, Deps, DepsMut, Env, MessageInfo, QueryRequest, Response, StdResult, }; +use cw_std::Coin; use crate::oper_perms::Permissions; use crate::{ @@ -34,7 +35,7 @@ pub fn instantiate( format!("crates.io:{CONTRACT_NAME}"), CONTRACT_VERSION, )?; - cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; + nibiru_ownable::initialize_owner(deps.storage, Some(&msg.owner))?; TO_ADDRS.save(deps.storage, &msg.to_addrs)?; OPERATORS.save(deps.storage, &msg.opers)?; IS_HALTED.save(deps.storage, &false)?; @@ -75,15 +76,14 @@ pub fn withdraw( denoms: BTreeSet, contract_addr: String, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let to_addr: String = match to { Some(given_to_addr) => given_to_addr, None => info.sender.to_string(), }; - let balances: AllBalanceResponse = + let balances: Vec = query_bank_balances(contract_addr, deps.as_ref())?; let balances: Vec = balances - .amount .iter() .filter(|b_coin| denoms.contains(&b_coin.denom)) .cloned() @@ -113,7 +113,7 @@ pub fn withdraw_all( to: Option, contract_addr: String, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let to_addr: String = match to { Some(given_to_addr) => given_to_addr, None => info.sender.to_string(), @@ -121,12 +121,10 @@ pub fn withdraw_all( let balances = query_bank_balances(contract_addr, deps.as_ref())?; let tx_msg = BankMsg::Send { to_address: to_addr.to_string(), - amount: balances.amount.clone(), + amount: balances.clone(), }; - let event = event_withdraw( - serde_json::to_string(&balances.amount)?.as_str(), - &to_addr, - ); + let event = + event_withdraw(serde_json::to_string(&balances)?.as_str(), &to_addr); LOGS.push_front( deps.storage, &Log { @@ -144,13 +142,11 @@ pub fn edit_opers( info: MessageInfo, action: oper_perms::Action, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let mut perms = Permissions::load(deps.storage)?; - let api = deps.api; match action { oper_perms::Action::AddOper { address } => { - let addr = api.addr_validate(address.as_str())?; - perms.operators.insert(addr.into_string()); + perms.operators.insert(address.clone()); OPERATORS.save(deps.storage, &perms.operators)?; let res = Response::new().add_attributes(vec![ @@ -178,7 +174,7 @@ pub fn toggle_halt( _env: Env, info: MessageInfo, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let new_is_halted = !IS_HALTED.load(deps.storage)?; IS_HALTED.save(deps.storage, &new_is_halted)?; Ok(Response::new().add_event(event_toggle_halt(&new_is_halted))) @@ -229,10 +225,14 @@ pub fn execute_update_ownership( deps: DepsMut, env: Env, info: MessageInfo, - action: cw_ownable::Action, + action: nibiru_ownable::Action, ) -> Result { - let ownership = - cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + let ownership = nibiru_ownable::update_ownership( + deps, + &env.block, + info.sender.as_str(), + action, + )?; Ok(Response::new().add_attributes(ownership.into_attributes())) } @@ -257,9 +257,9 @@ pub fn query( let perms_status: PermsStatus = query_perms_status(deps)?; Ok(to_json_binary(&perms_status)?) } - QueryMsg::Ownership {} => { - Ok(to_json_binary(&cw_ownable::get_ownership(deps.storage)?)?) - } + QueryMsg::Ownership {} => Ok(to_json_binary( + &nibiru_ownable::get_ownership(deps.storage)?, + )?), } } @@ -273,28 +273,25 @@ pub fn query_accepted_denoms(deps: Deps) -> StdResult> { /// use broker_bank::contract::query_bank_balances; /// use cosmwasm_std::{ /// testing::{mock_dependencies, mock_env}, -/// AllBalanceResponse, DepsMut, Env, StdResult}; +/// DepsMut, Env, StdResult, Coin}; /// /// let env: Env = mock_env(); /// let mut deps = mock_dependencies(); /// let mut deps: DepsMut = deps.as_mut(); /// let contract_addr = env.contract.address.to_string(); -/// let balances: StdResult = +/// let balances: StdResult> = /// query_bank_balances(contract_addr.to_string(), deps.as_ref()); /// assert!(balances.is_ok()) /// ``` -pub fn query_bank_balances( - addr: String, - deps: Deps, -) -> StdResult { - let query_result = +pub fn query_bank_balances(addr: String, deps: Deps) -> StdResult> { + let query_result: Option = deps.querier .query(&QueryRequest::Bank(BankQuery::AllBalances { address: addr, }))?; - let balances: AllBalanceResponse = match query_result { - Some(res) => res, - None => AllBalanceResponse::default(), + let balances: Vec = match query_result { + Some(res) => res.amount, + None => Vec::new(), }; Ok(balances) } @@ -369,7 +366,7 @@ pub mod tests { opers: opers.to_vec(), sender: not_owner, exec_msg: ExecuteMsg::UpdateOwnership( - cw_ownable::Action::TransferOwnership { + nibiru_ownable::Action::TransferOwnership { new_owner: String::from("new_owner"), expiry: None, }, diff --git a/contracts/broker-bank/src/error.rs b/contracts/broker-bank/src/error.rs index ce41389..9d949ea 100644 --- a/contracts/broker-bank/src/error.rs +++ b/contracts/broker-bank/src/error.rs @@ -12,7 +12,7 @@ pub enum ContractError { SerdeJson(String), #[error("{0}")] - Ownership(#[from] cw_ownable::OwnershipError), + Ownership(#[from] nibiru_ownable::OwnershipError), // #[error("serde_json error: {err:?}")] // SerdeJson { err: serde_json::error::Error }, diff --git a/contracts/broker-bank/src/msgs.rs b/contracts/broker-bank/src/msgs.rs index 0b377dd..6e75f0a 100644 --- a/contracts/broker-bank/src/msgs.rs +++ b/contracts/broker-bank/src/msgs.rs @@ -5,7 +5,7 @@ use cosmwasm_std as cw; use crate::oper_perms; -#[cw_ownable::cw_ownable_execute] +#[nibiru_ownable::ownable_execute] #[cw_serde] pub enum ExecuteMsg { /// Send coins to an account the set of "TO_ADDRS", appending transaction @@ -32,7 +32,7 @@ pub enum ExecuteMsg { // TODO: feat(broker-bank): Clear logs tx } -#[cw_ownable::cw_ownable_query] +#[nibiru_ownable::ownable_query] #[cw_serde] #[derive(cosmwasm_schema::QueryResponses)] pub enum QueryMsg { diff --git a/contracts/broker-bank/src/oper_perms.rs b/contracts/broker-bank/src/oper_perms.rs index 3c34a6f..e920b57 100644 --- a/contracts/broker-bank/src/oper_perms.rs +++ b/contracts/broker-bank/src/oper_perms.rs @@ -45,10 +45,10 @@ impl Permissions { } pub fn load(storage: &dyn Storage) -> Result { - let owner = cw_ownable::get_ownership(storage)?.owner; + let owner = nibiru_ownable::get_ownership(storage)?.owner; let opers = OPERATORS.load(storage)?; Ok(Permissions { - owner: owner.map(|addr| addr.into_string()), + owner: owner.map(|addr| addr.to_string()), operators: opers, }) } diff --git a/contracts/broker-staking/.cargo/config b/contracts/broker-staking/.cargo/config deleted file mode 100644 index 8a76ed5..0000000 --- a/contracts/broker-staking/.cargo/config +++ /dev/null @@ -1,7 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" - diff --git a/contracts/broker-staking/.cargo/config.toml b/contracts/broker-staking/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/broker-staking/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/broker-staking/Cargo.toml b/contracts/broker-staking/Cargo.toml index 30ce203..32acb65 100644 --- a/contracts/broker-staking/Cargo.toml +++ b/contracts/broker-staking/Cargo.toml @@ -17,12 +17,10 @@ crate-type = ["cdylib", "rlib"] [features] # for quicker tests, cargo test --lib -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] [dependencies] cosmwasm-schema = { workspace = true } -cw-ownable = { workspace = true } +nibiru-ownable = { workspace = true } nibiru-std = { workspace = true } cosmwasm-std = { workspace = true } cw20.workspace = true diff --git a/contracts/broker-staking/src/contract.rs b/contracts/broker-staking/src/contract.rs index a15ae9e..4f732c9 100644 --- a/contracts/broker-staking/src/contract.rs +++ b/contracts/broker-staking/src/contract.rs @@ -25,7 +25,7 @@ pub fn instantiate( msg: BrokerBankInstantiateMsg, ) -> StdResult { // Managers validation - cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; + nibiru_ownable::initialize_owner(deps.storage, Some(&msg.owner))?; TO_ADDRS.save(deps.storage, &msg.to_addrs)?; OPERATORS.save(deps.storage, &msg.opers)?; IS_HALTED.save(deps.storage, &false)?; @@ -68,7 +68,7 @@ pub fn unstake( info: MessageInfo, unstake_msgs: Vec, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let mut messages: Vec = vec![]; for msg in unstake_msgs.iter() { @@ -168,8 +168,8 @@ pub fn query( let perms_status: PermsStatus = query_perms_status(deps)?; Ok(to_json_binary(&perms_status)?) } - QueryMsg::Ownership {} => { - Ok(to_json_binary(&cw_ownable::get_ownership(deps.storage)?)?) - } + QueryMsg::Ownership {} => Ok(to_json_binary( + &nibiru_ownable::get_ownership(deps.storage)?, + )?), } } diff --git a/contracts/broker-staking/src/msg.rs b/contracts/broker-staking/src/msg.rs index fa4a66a..abfbb97 100644 --- a/contracts/broker-staking/src/msg.rs +++ b/contracts/broker-staking/src/msg.rs @@ -7,7 +7,7 @@ use cosmwasm_std::Uint128; /// Enum respresenting message types for the execute entry point. /// These express the different ways in which one can invoke the contract /// and broadcast tx messages against it. -#[cw_ownable::cw_ownable_execute] +#[nibiru_ownable::ownable_execute] #[cw_serde] pub enum ExecuteMsg { /// Toggles whether "operators" can invoke the smart contract. This acts a diff --git a/contracts/broker-staking/src/testing.rs b/contracts/broker-staking/src/testing.rs index 815a178..7978667 100644 --- a/contracts/broker-staking/src/testing.rs +++ b/contracts/broker-staking/src/testing.rs @@ -57,7 +57,7 @@ pub fn test_assert_owner() -> TestResult { opers: opers.to_vec(), sender: not_owner, exec_msg: ExecuteMsg::UpdateOwnership( - cw_ownable::Action::TransferOwnership { + nibiru_ownable::Action::TransferOwnership { new_owner: String::from("new_owner"), expiry: None, }, diff --git a/contracts/config.toml b/contracts/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/core-cw3-flex-msig/.cargo/config.toml b/contracts/core-cw3-flex-msig/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/core-cw3-flex-msig/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/core-cw3-flex-msig/Cargo.toml b/contracts/core-cw3-flex-msig/Cargo.toml index 0999733..3119b77 100644 --- a/contracts/core-cw3-flex-msig/Cargo.toml +++ b/contracts/core-cw3-flex-msig/Cargo.toml @@ -13,7 +13,6 @@ 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 = [] @@ -21,17 +20,18 @@ library = [] cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } cosmwasm-schema = { workspace = true } -cw-utils = "1.0.2" +cw-utils = { workspace = true } cw2 = { workspace = true } cw3 = { workspace = true } cw3-fixed-multisig = { workspace = true } cw4 = { workspace = true } cw20 = { workspace = true } -schemars = "0.8.15" +schemars = { workspace = true } serde = { version = "1.0.190", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.23" } +thiserror = { workspace = true } [dev-dependencies] -cw4-group = { version = "1.1.1" } -cw-multi-test = "0.17.0" -cw20-base = { version = "1.1.1" } \ No newline at end of file +cw4-group = { workspace = true } +cw-multi-test = { workspace = true } +cw20-base = { workspace = true } +easy-addr = { workspace = true } \ No newline at end of file diff --git a/contracts/core-cw3-flex-msig/src/contract.rs b/contracts/core-cw3-flex-msig/src/contract.rs index 911905b..223207d 100644 --- a/contracts/core-cw3-flex-msig/src/contract.rs +++ b/contracts/core-cw3-flex-msig/src/contract.rs @@ -513,6 +513,7 @@ mod tests { coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp, Uint128, }; + use super::*; use cw2::{query_contract_info, ContractVersion}; use cw20::{Cw20Coin, UncheckedDenom}; use cw3::{DepositError, UncheckedDepositInfo}; @@ -523,16 +524,16 @@ mod tests { Executor, SudoMsg, }; use cw_utils::{Duration, Threshold}; + use easy_addr::addr; - use super::*; - - const OWNER: &str = "admin0001"; - const VOTER1: &str = "voter0001"; - const VOTER2: &str = "voter0002"; - const VOTER3: &str = "voter0003"; - const VOTER4: &str = "voter0004"; - const VOTER5: &str = "voter0005"; - const SOMEBODY: &str = "somebody"; + const OWNER: &str = addr!("admin0001"); + const VOTER1: &str = addr!("voter0001"); + const VOTER2: &str = addr!("voter0002"); + const VOTER3: &str = addr!("voter0003"); + const VOTER4: &str = addr!("voter0004"); + const VOTER5: &str = addr!("voter0005"); + const SOMEBODY: &str = addr!("somebody"); + const NEWBIE: &str = addr!("newbie"); fn member>(addr: T, weight: u64) -> Member { Member { @@ -1926,7 +1927,7 @@ mod tests { // updates VOTER2 power to 21 -> with snapshot, vote doesn't pass proposal // adds NEWBIE with 2 power -> with snapshot, invalid vote // removes VOTER3 -> with snapshot, can vote on proposal - let newbie: &str = "newbie"; + let newbie: &str = NEWBIE; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], add: vec![member(VOTER2, 21), member(newbie, 2)], @@ -2226,7 +2227,7 @@ mod tests { app.update_block(|block| block.height += 2); // admin changes the group (3 -> 0, 2 -> 9, 0 -> 29) - total = 56, require 29 to pass - let newbie: &str = "newbie"; + let newbie: &str = NEWBIE; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], add: vec![member(VOTER2, 9), member(newbie, 29)], @@ -2331,7 +2332,7 @@ mod tests { app.update_block(|block| block.height += 2); // admin changes the group (3 -> 0, 2 -> 9, 0 -> 28) - total = 55, require 28 to pass - let newbie: &str = "newbie"; + let newbie: &str = NEWBIE; let update_msg = cw4_group::msg::ExecuteMsg::UpdateMembers { remove: vec![VOTER3.into()], add: vec![member(VOTER2, 9), member(newbie, 29)], diff --git a/contracts/core-shifter/.cargo/config b/contracts/core-shifter/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/core-shifter/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/core-shifter/.cargo/config.toml b/contracts/core-shifter/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/core-shifter/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/core-shifter/Cargo.toml b/contracts/core-shifter/Cargo.toml index 3ab9070..f610908 100644 --- a/contracts/core-shifter/Cargo.toml +++ b/contracts/core-shifter/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/NibiruChain/cw-nibiru" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] @@ -22,8 +21,9 @@ nibiru-std = { workspace = true } thiserror = { workspace = true } schemars = "0.8.15" serde = { version = "1.0.188", default-features = false, features = ["derive"] } -cw-ownable = { workspace = true } +nibiru-ownable = { workspace = true } cw2 = { workspace = true } [dev-dependencies] -anyhow = { workspace = true } \ No newline at end of file +anyhow = { workspace = true } +easy-addr = { workspace = true } \ No newline at end of file diff --git a/contracts/core-shifter/out.json b/contracts/core-shifter/out.json new file mode 100644 index 0000000..e69de29 diff --git a/contracts/core-shifter/src/contract.rs b/contracts/core-shifter/src/contract.rs index 33e7ef3..f8b778b 100644 --- a/contracts/core-shifter/src/contract.rs +++ b/contracts/core-shifter/src/contract.rs @@ -118,10 +118,14 @@ fn execute_update_ownership( deps: DepsMut, env: Env, info: MessageInfo, - action: cw_ownable::Action, -) -> Result { - let ownership = - cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + action: nibiru_ownable::Action, +) -> Result { + let ownership = nibiru_ownable::update_ownership( + deps, + &env.block, + info.sender.as_str(), + action, + )?; Ok(Response::new().add_attributes(ownership.into_attributes())) } @@ -191,6 +195,8 @@ pub mod tests { use cosmwasm_std::{coins, testing}; use std::collections::BTreeSet; + use easy_addr::addr; + // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- @@ -244,7 +250,7 @@ pub mod tests { #[test] fn test_exec_edit_opers_add() -> TestResult { let (mut deps, _env, _info) = t::setup_contract()?; - let new_member = "new_member"; + let new_member = addr!("new_member"); let perms = Permissions::load(&deps.storage)?; let not_has: bool = !perms.is_owner(new_member); assert!(not_has); diff --git a/contracts/core-shifter/src/error.rs b/contracts/core-shifter/src/error.rs index d021256..d4eb51e 100644 --- a/contracts/core-shifter/src/error.rs +++ b/contracts/core-shifter/src/error.rs @@ -9,7 +9,7 @@ pub enum ContractError { Std(#[from] StdError), #[error("{0}")] - Ownership(#[from] cw_ownable::OwnershipError), + Ownership(#[from] nibiru_ownable::OwnershipError), #[error("insufficient permissions: sender is not a contract operator ({sender:?})")] NoOperatorPerms { sender: String }, diff --git a/contracts/core-shifter/src/msgs.rs b/contracts/core-shifter/src/msgs.rs index 0db1ded..2f5df8b 100644 --- a/contracts/core-shifter/src/msgs.rs +++ b/contracts/core-shifter/src/msgs.rs @@ -8,7 +8,7 @@ pub struct InitMsg { } /// ExecuteMsg specifies the args for the execute entry point of the contract. -#[cw_ownable::cw_ownable_execute] +#[nibiru_ownable::ownable_execute] #[cw_serde] pub enum ExecuteMsg { ShiftSwapInvariant { diff --git a/contracts/core-shifter/src/state.rs b/contracts/core-shifter/src/state.rs index d6ca58f..03ebac5 100644 --- a/contracts/core-shifter/src/state.rs +++ b/contracts/core-shifter/src/state.rs @@ -35,10 +35,10 @@ impl Permissions { } pub fn load(storage: &dyn Storage) -> Result { - let owner = cw_ownable::get_ownership(storage)?.owner; + let owner = nibiru_ownable::get_ownership(storage)?.owner; let opers = OPERATORS.load(storage)?; Ok(Permissions { - owner: owner.map(|addr| addr.into_string()), + owner: owner.map(|addr| addr.to_string()), operators: opers, }) } @@ -50,9 +50,9 @@ impl Permissions { pub fn instantiate_perms( owner: Option<&str>, storage: &mut dyn Storage, - api: &dyn Api, + _api: &dyn Api, ) -> Result<(), ContractError> { - cw_ownable::initialize_owner(storage, api, owner)?; + nibiru_ownable::initialize_owner(storage, owner)?; Ok(OPERATORS.save(storage, &BTreeSet::default())?) } diff --git a/contracts/core-shifter/vote.json b/contracts/core-shifter/vote.json new file mode 100644 index 0000000..d3e9737 --- /dev/null +++ b/contracts/core-shifter/vote.json @@ -0,0 +1,6 @@ +{ + "vote": { + "proposal_id": 73, + "vote": "yes" + } +} diff --git a/contracts/core-token-vesting-v2/.cargo/config b/contracts/core-token-vesting-v2/.cargo/config deleted file mode 100644 index 8a76ed5..0000000 --- a/contracts/core-token-vesting-v2/.cargo/config +++ /dev/null @@ -1,7 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" - diff --git a/contracts/core-token-vesting-v2/.cargo/config.toml b/contracts/core-token-vesting-v2/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/core-token-vesting-v2/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/core-token-vesting-v2/Cargo.toml b/contracts/core-token-vesting-v2/Cargo.toml index 3cd727c..409a8e8 100644 --- a/contracts/core-token-vesting-v2/Cargo.toml +++ b/contracts/core-token-vesting-v2/Cargo.toml @@ -17,8 +17,6 @@ crate-type = ["cdylib", "rlib"] [features] # for quicker tests, cargo test --lib -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] [dependencies] cosmwasm-schema = "1.4.0" @@ -32,4 +30,4 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } [dev-dependencies] -anyhow = { workspace = true } +anyhow = { workspace = true } \ No newline at end of file diff --git a/contracts/core-token-vesting/.cargo/config b/contracts/core-token-vesting/.cargo/config deleted file mode 100644 index 8a76ed5..0000000 --- a/contracts/core-token-vesting/.cargo/config +++ /dev/null @@ -1,7 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" - diff --git a/contracts/core-token-vesting/.cargo/config.toml b/contracts/core-token-vesting/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/core-token-vesting/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/core-token-vesting/Cargo.toml b/contracts/core-token-vesting/Cargo.toml index 7a2d3bf..0905e6c 100644 --- a/contracts/core-token-vesting/Cargo.toml +++ b/contracts/core-token-vesting/Cargo.toml @@ -17,8 +17,6 @@ crate-type = ["cdylib", "rlib"] [features] # for quicker tests, cargo test --lib -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] [dependencies] cosmwasm-schema = "1.4.0" @@ -32,4 +30,4 @@ serde = { version = "1.0.188", default-features = false, features = ["derive"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } [dev-dependencies] -anyhow = { workspace = true } \ No newline at end of file +anyhow = { workspace = true } diff --git a/contracts/incentives/.cargo/config b/contracts/incentives/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/incentives/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/incentives/.cargo/config.toml b/contracts/incentives/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/incentives/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/incentives/Cargo.toml b/contracts/incentives/Cargo.toml index 806a572..a98a494 100644 --- a/contracts/incentives/Cargo.toml +++ b/contracts/incentives/Cargo.toml @@ -8,22 +8,24 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] [dependencies] -cw-utils = { version = "1.0.2" } -cw2 = { version = "1.1.1" } -cw20 = { version = "1.1.1" } -cosmwasm-schema = { version = "1.4.0" } -cosmwasm-std = { version = "1.4.0" } -cw-storage-plus = { version = "1.1.0" } +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw2 = { workspace = true } +cw20 = { workspace = true } +nibiru-std = { workspace = true } schemars = "0.8.15" serde = { version = "1.0.188", default-features = false, features = ["derive"] } serde-json-wasm = "1.0.0" -thiserror = { version = "1.0.49" } +thiserror = { workspace = true } lockup = { workspace = true } [dev-dependencies] -cw-multi-test = { workspace = true } \ No newline at end of file +cw-multi-test = { workspace = true } +easy-addr = { workspace = true } +anyhow = { workspace = true } \ No newline at end of file diff --git a/contracts/incentives/src/contract.rs b/contracts/incentives/src/contract.rs index 3c94db9..52e4f61 100644 --- a/contracts/incentives/src/contract.rs +++ b/contracts/incentives/src/contract.rs @@ -216,7 +216,7 @@ fn execute_withdraw_rewards( &lockup::msgs::QueryMsg::LocksByDenomAndAddressBetween { denom: program.lockup_denom.clone(), unlocking_after: epoch.for_coins_unlocking_after, - address: info.sender.clone(), + address: info.sender.to_string(), locked_before: epoch.for_coins_locked_before, }, )?; @@ -240,11 +240,18 @@ fn execute_withdraw_rewards( Decimal::from_ratio(qualified_locked_amount, epoch.total_locked); println!("ownership ratio: {:?}", user_ownership_ratio.to_string()); for coin in epoch.to_distribute { + let coin_amount: Uint128 = coin + .amount + .checked_multiply_ratio( + qualified_locked_amount, + epoch.total_locked, + ) + .unwrap(); add_coins( &mut to_distribute, Coin { denom: coin.denom, - amount: coin.amount * user_ownership_ratio, + amount: coin_amount, }, ) } @@ -265,6 +272,14 @@ fn execute_withdraw_rewards( .unwrap(); println!("distributing: {:?}", &to_distribute); + let to_distribute: Vec = to_distribute + .into_iter() + .filter(|coin| !coin.amount.is_zero()) + .collect(); + + if to_distribute.is_empty() { + return Ok(Response::new()); + } Ok(Response::new().add_message(BankMsg::Send { to_address: info.sender.to_string(), amount: to_distribute, @@ -326,10 +341,8 @@ fn execute_process_epoch( )?; // identify how much is the total locked - let total_locked = locks - .iter() - .map(|lock| -> Uint128 { lock.coin.amount }) - .sum::(); + let total_locked = + locks.iter().map(|lock| lock.coin.amount).sum::(); // then we identify how many coins we need to pay // based on the program funding diff --git a/contracts/incentives/src/error.rs b/contracts/incentives/src/error.rs index 1b9088d..6a81e9b 100644 --- a/contracts/incentives/src/error.rs +++ b/contracts/incentives/src/error.rs @@ -1,7 +1,4 @@ use cosmwasm_std::StdError; -#[cfg(feature = "backtraces")] -use std::backtrace::Backtrace; - use thiserror::Error; #[allow(dead_code)] diff --git a/contracts/incentives/src/state.rs b/contracts/incentives/src/state.rs index 61f15fd..d2c4aad 100644 --- a/contracts/incentives/src/state.rs +++ b/contracts/incentives/src/state.rs @@ -49,7 +49,7 @@ pub struct FundingIndexes<'a> { pub(crate) pay_from_epoch: MultiIndex<'a, (u64, u64), Funding, u64>, } -impl<'a> IndexList for FundingIndexes<'a> { +impl IndexList for FundingIndexes<'_> { fn get_indexes( &'_ self, ) -> Box> + '_> { @@ -58,7 +58,7 @@ impl<'a> IndexList for FundingIndexes<'a> { } } -pub fn funding<'a>() -> IndexedMap<'a, u64, Funding, FundingIndexes<'a>> { +pub fn funding<'a>() -> IndexedMap> { let indexes = FundingIndexes { pay_from_epoch: MultiIndex::new( |_bz, funding: &Funding| -> (_, _) { @@ -69,5 +69,5 @@ pub fn funding<'a>() -> IndexedMap<'a, u64, Funding, FundingIndexes<'a>> { ), }; - return IndexedMap::new("funding", indexes); + IndexedMap::new("funding", indexes) } diff --git a/contracts/incentives/src/testing.rs b/contracts/incentives/src/testing.rs index 0a67b1c..016bfce 100644 --- a/contracts/incentives/src/testing.rs +++ b/contracts/incentives/src/testing.rs @@ -6,21 +6,32 @@ mod integration_test { use cosmwasm_std::{from_json, Addr, Coin}; use cw_multi_test::{App, BankSudo, ContractWrapper, Executor}; + use easy_addr::addr; + use nibiru_std::errors::TestResult; - const ROOT: &str = "root"; - const INCENTIVES: &str = "contract1"; - const LOCKUP: &str = "contract0"; + const ADDR_ROOT: &str = addr!("root"); + + #[derive(Debug, Clone)] + pub struct TestContracts { + pub contract_incentives_addr: Addr, + pub contract_lockup_addr: Addr, + } + pub struct TestDeps { + pub app: App, + pub contracts: TestContracts, + } fn create_program( app: &mut App, + contracts: TestContracts, denom: String, epochs: u64, epoch_block_duration: u64, min_lockup_blocks: u64, ) { app.execute_contract( - Addr::unchecked(ROOT), - Addr::unchecked(INCENTIVES), + Addr::unchecked(ADDR_ROOT), + contracts.contract_incentives_addr, &ExecuteMsg::CreateProgram { denom, epochs, @@ -34,18 +45,19 @@ mod integration_test { fn fund_program( app: &mut App, + contracts: TestContracts, _program_id: u64, coins: &[Coin], ) -> Vec { app.execute_contract( - Addr::unchecked(ROOT), - Addr::unchecked(INCENTIVES), + Addr::unchecked(ADDR_ROOT), + contracts.contract_incentives_addr, &ExecuteMsg::FundProgram { id: 1 }, coins, ) .unwrap(); - app.wrap().query_all_balances(ROOT).unwrap() + app.wrap().query_all_balances(ADDR_ROOT).unwrap() } fn mint(app: &mut App, to: &Addr, coins: &[Coin]) { @@ -59,12 +71,18 @@ mod integration_test { .unwrap(); } - fn mint_and_lock(app: &mut App, user: &Addr, coins: &[Coin], blocks: u64) { + fn mint_and_lock( + app: &mut App, + contracts: TestContracts, + user: &Addr, + coins: &[Coin], + blocks: u64, + ) { mint(app, user, coins); // we make alice lock some atoms app.execute_contract( user.clone(), - Addr::unchecked(LOCKUP), + contracts.contract_lockup_addr, &lockup::msgs::ExecuteMsg::Lock { blocks }, coins, ) @@ -73,12 +91,13 @@ mod integration_test { fn withdraw_rewards( app: &mut App, + contracts: TestContracts, user: &Addr, _program_id: u64, ) -> Vec { app.execute_contract( user.clone(), - Addr::unchecked(INCENTIVES), + contracts.contract_incentives_addr, &crate::msgs::ExecuteMsg::WithdrawRewards { id: 1 }, &[], ) @@ -87,11 +106,15 @@ mod integration_test { app.wrap().query_all_balances(user).unwrap() } - fn process_epoch(app: &mut App, _program_id: u64) -> EpochInfo { + fn process_epoch( + app: &mut App, + contracts: TestContracts, + _program_id: u64, + ) -> EpochInfo { from_json::( &app.execute_contract( - Addr::unchecked(ROOT), - Addr::unchecked(INCENTIVES), + Addr::unchecked(ADDR_ROOT), + contracts.contract_incentives_addr, &ExecuteMsg::ProcessEpoch { id: 1 }, &[], ) @@ -102,7 +125,7 @@ mod integration_test { .unwrap() } - fn app() -> App { + fn app() -> anyhow::Result { let mut app = App::default(); // note don't break the order otherwise contracts will have different addresses // which renders the const in the module useless TODO: maybe do better. @@ -113,69 +136,92 @@ mod integration_test { lockup::contract::query, )); let code = app.store_code(lockup_contract); - app.instantiate_contract( + let contract_lockup_addr = app.instantiate_contract( code, - Addr::unchecked(ROOT), + Addr::unchecked(ADDR_ROOT), &lockup::msgs::InstantiateMsg {}, &[], "lockup", None, - ) - .unwrap(); + )?; let incentives_contract = Box::new(ContractWrapper::new(execute, instantiate, query)); let code = app.store_code(incentives_contract); - app.instantiate_contract( + let contract_incentives_addr = app.instantiate_contract( code, - Addr::unchecked(ROOT), + Addr::unchecked(ADDR_ROOT), &InstantiateMsg { - lockup_contract_address: Addr::unchecked(LOCKUP), + lockup_contract_address: contract_lockup_addr.clone(), }, &[], "incentives", None, - ) - .unwrap(); + )?; - app + Ok(TestDeps { + app, + contracts: TestContracts { + contract_incentives_addr, + contract_lockup_addr, + }, + }) } #[test] - fn flow() { - let mut app = app(); - let _lockup_addr = Addr::unchecked(LOCKUP); - let _incentives_addr = Addr::unchecked(INCENTIVES); + fn flow() -> TestResult { + let test_deps = app()?; + let mut app = test_deps.app; + let contracts = test_deps.contracts; - let alice = Addr::unchecked("alice"); - let bob = Addr::unchecked("bob"); + let alice = Addr::unchecked(addr!("alice")); + let bob = Addr::unchecked(addr!("bob")); // mint coins mint( &mut app, - &Addr::unchecked(ROOT), + &Addr::unchecked(ADDR_ROOT), &[ - Coin::new(1_000_000, "ATOM"), - Coin::new(1_000_000, "OSMO"), - Coin::new(1_000_000, "LUNA"), + Coin::new(1_000_000u32, "ATOM"), + Coin::new(1_000_000u32, "OSMO"), + Coin::new(1_000_000u32, "LUNA"), ], ); // we make alice lock some lp coins - mint_and_lock(&mut app, &alice, &[Coin::new(100, "NIBI_LP")], 100); + let blocks = 100; + mint_and_lock( + &mut app, + contracts.clone(), + &alice, + &[Coin::new(100u32, "NIBI_LP")], + blocks, + ); // now we create a new incentives program - create_program(&mut app, "NIBI_LP".to_string(), 5, 5, 50); + create_program( + &mut app, + contracts.clone(), + "NIBI_LP".to_string(), + 5, + 5, + 50, + ); // now we fund the incentives program - let balance = fund_program(&mut app, 1, &[Coin::new(1_000, "ATOM")]); + let balance = fund_program( + &mut app, + contracts.clone(), + 1, + &[Coin::new(1_000u32, "ATOM")], + ); println!("{:?}", balance,); let funding: Vec = app .wrap() .query_wasm_smart( - INCENTIVES, + &contracts.contract_incentives_addr, &QueryMsg::ProgramFunding { program_id: 1 }, ) .unwrap(); @@ -185,18 +231,25 @@ mod integration_test { block.height += 6 // shift +1 because epoch can be processed after the epoch block }); - let epoch_info = process_epoch(&mut app, 1); + let epoch_info = process_epoch(&mut app, contracts.clone(), 1); println!("{:?}", epoch_info); // withdraw rewards for alice at epoch 1 - let alice_rewards = withdraw_rewards(&mut app, &alice, 1); + let alice_rewards = + withdraw_rewards(&mut app, contracts.clone(), &alice, 1); // expected: 200ATOM coins - assert_eq!(vec![Coin::new(200, "ATOM")], alice_rewards,); + assert_eq!(vec![Coin::new(200u32, "ATOM")], alice_rewards,); // add bob lock - mint_and_lock(&mut app, &bob, &[Coin::new(200, "NIBI_LP")], 300); + mint_and_lock( + &mut app, + contracts.clone(), + &bob, + &[Coin::new(200u32, "NIBI_LP")], + 300, + ); // bob qualifies for next epoch app.update_block(|block| { @@ -204,74 +257,88 @@ mod integration_test { }); // process epoch - let epoch_info = process_epoch(&mut app, 1); + let epoch_info = process_epoch(&mut app, contracts.clone(), 1); println!("{:?}", epoch_info); // withdraw rewards for alice at epoch 2 - let alice_balance = withdraw_rewards(&mut app, &alice, 1); + let alice_balance = + withdraw_rewards(&mut app, contracts.clone(), &alice, 1); // expected: 200 + 0.33*200 ATOM coins - assert_eq!(vec![Coin::new(200 + 66, "ATOM")], alice_balance,); + assert_eq!(vec![Coin::new(200u32 + 66u32, "ATOM")], alice_balance,); // withdraw rewards for bob at epoch 2 - let bob_balance = withdraw_rewards(&mut app, &bob, 1); + let bob_balance = withdraw_rewards(&mut app, contracts.clone(), &bob, 1); // expected: 200 * 0.66666666 ATOM - assert_eq!(vec![Coin::new(133, "ATOM")], bob_balance,); + assert_eq!(vec![Coin::new(133u32, "ATOM")], bob_balance,); app.update_block(|block| block.height += 1); // add more funding - fund_program(&mut app, 1, &[Coin::new(1000, "OSMO")]); + fund_program( + &mut app, + contracts.clone(), + 1, + &[Coin::new(1000u32, "OSMO")], + ); // go to epoch 3 block and process it app.update_block(|block| block.height += 4); - let epoch_info = process_epoch(&mut app, 1); + let epoch_info = process_epoch(&mut app, contracts.clone(), 1); println!("{:?}", epoch_info); // go to epoch 4 block and process it app.update_block(|block| block.height += 5); - let epoch_info = process_epoch(&mut app, 1); + let epoch_info = process_epoch(&mut app, contracts.clone(), 1); println!("{:?}", epoch_info); // withdraw rewards for alice at epoch 3-4 - let alice_balance = withdraw_rewards(&mut app, &alice, 1); + let alice_balance = + withdraw_rewards(&mut app, contracts.clone(), &alice, 1); // withdraw rewards for bob at epoch 3-4 - let bob_balance = withdraw_rewards(&mut app, &bob, 1); + let bob_balance = withdraw_rewards(&mut app, contracts.clone(), &bob, 1); assert_eq!( - vec![Coin::new(399, "ATOM"), Coin::new(442, "OSMO")], + vec![Coin::new(399u32, "ATOM"), Coin::new(444u32, "OSMO")], bob_balance, ); assert_eq!( - vec![Coin::new(398, "ATOM"), Coin::new(220, "OSMO")], + vec![Coin::new(398u32, "ATOM"), Coin::new(222u32, "OSMO")], alice_balance, ); // create a new funding for last epoch - fund_program(&mut app, 1, &[Coin::new(1000, "OSMO")]); + fund_program( + &mut app, + contracts.clone(), + 1, + &[Coin::new(1000u32, "OSMO")], + ); // fast forward to epoch 5 app.update_block(|block| block.height += 5); // process epoch 5 app.update_block(|block| block.height += 5); - let epoch_info = process_epoch(&mut app, 1); + let epoch_info = process_epoch(&mut app, contracts.clone(), 1); println!("{:?}", epoch_info); // finalize distribution - let alice_balance = withdraw_rewards(&mut app, &alice, 1); + let alice_balance = + withdraw_rewards(&mut app, contracts.clone(), &alice, 1); assert_eq!( - vec![Coin::new(464, "ATOM"), Coin::new(664, "OSMO")], + vec![Coin::new(464u32, "ATOM"), Coin::new(666u32, "OSMO")], alice_balance, ); - let bob_balance = withdraw_rewards(&mut app, &bob, 1); + let bob_balance = withdraw_rewards(&mut app, contracts, &bob, 1); assert_eq!( - vec![Coin::new(532, "ATOM"), Coin::new(1330, "OSMO")], + vec![Coin::new(532u32, "ATOM"), Coin::new(1332u32, "OSMO")], bob_balance, ); + Ok(()) } } diff --git a/contracts/lockup/.cargo/config b/contracts/lockup/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/lockup/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/lockup/.cargo/config.toml b/contracts/lockup/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/lockup/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/lockup/Cargo.toml b/contracts/lockup/Cargo.toml index 5e1f09c..1060dd4 100644 --- a/contracts/lockup/Cargo.toml +++ b/contracts/lockup/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/lockup/src/contract.rs b/contracts/lockup/src/contract.rs index bc34feb..83c04d8 100644 --- a/contracts/lockup/src/contract.rs +++ b/contracts/lockup/src/contract.rs @@ -140,7 +140,7 @@ pub(crate) fn execute_lock( &Lock { id, coin: coin.clone(), - owner: info.sender.clone(), + owner: info.sender.to_string(), duration_blocks: blocks, start_block: env.block.height, end_block: NOT_UNLOCKING_BLOCK_IDENTIFIER, @@ -265,12 +265,12 @@ mod tests { use crate::state::Lock; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_json, Addr, Coin, DepsMut, Env}; + use cosmwasm_std::{from_json, Coin, DepsMut, Env}; /// A 'TestLock' is struct representating an "owner" locking "coins" for /// some "duration". struct TestLock { - owner: Addr, + owner: String, duration: u64, coins: Vec, } @@ -320,15 +320,15 @@ mod tests { init(deps.as_mut()); let lock_1 = TestLock { - owner: Addr::unchecked("alice"), + owner: String::from("alice"), duration: 100, - coins: vec![Coin::new(100, "ATOM"), Coin::new(300, "LUNA")], + coins: vec![Coin::new(100u128, "ATOM"), Coin::new(300u128, "LUNA")], }; let lock_2 = TestLock { - owner: Addr::unchecked("bob"), + owner: String::from("bob"), duration: 50, - coins: vec![Coin::new(200, "ATOM"), Coin::new(700, "NIBI")], + coins: vec![Coin::new(200u128, "ATOM"), Coin::new(700u128, "NIBI")], }; create_lock(deps.as_mut(), &env, &lock_1); create_lock(deps.as_mut(), &env, &lock_2); @@ -348,7 +348,7 @@ mod tests { denom: denom.to_string(), unlocking_after, }, - coins: vec![Coin::new(100, denom), Coin::new(200, denom)], + coins: vec![Coin::new(100u128, denom), Coin::new(200u128, denom)], }); cases.push(CaseLocksByDenomUnlockingAfter { msg: QueryMsg::LocksByDenomAndAddressUnlockingAfter { @@ -356,7 +356,7 @@ mod tests { unlocking_after: 0, address: lock_1.owner.clone(), }, - coins: vec![Coin::new(100, denom)], + coins: vec![Coin::new(100u128, denom)], }); cases.push(CaseLocksByDenomUnlockingAfter { msg: QueryMsg::LocksByDenomAndAddressUnlockingAfter { @@ -364,7 +364,7 @@ mod tests { unlocking_after: 0, address: lock_2.owner.clone(), }, - coins: vec![Coin::new(200, denom)], + coins: vec![Coin::new(200u128, denom)], }); let denom = "LUNA"; @@ -373,7 +373,7 @@ mod tests { denom: denom.to_string(), unlocking_after, }, - coins: vec![Coin::new(300, denom)], + coins: vec![Coin::new(300u128, denom)], }); let denom = "NIBI"; @@ -382,7 +382,7 @@ mod tests { denom: denom.to_string(), unlocking_after, }, - coins: vec![Coin::new(700, denom)], + coins: vec![Coin::new(700u128, denom)], }); cases.push(CaseLocksByDenomUnlockingAfter { @@ -399,7 +399,7 @@ mod tests { unlocking_after, address: lock_2.owner, }, - coins: vec![Coin::new(700, denom)], + coins: vec![Coin::new(700u128, denom)], }); for case in &cases { diff --git a/contracts/lockup/src/error.rs b/contracts/lockup/src/error.rs index 6e23521..a2f9599 100644 --- a/contracts/lockup/src/error.rs +++ b/contracts/lockup/src/error.rs @@ -1,7 +1,4 @@ use cosmwasm_std::StdError; -#[cfg(feature = "backtraces")] -use std::backtrace::Backtrace; - use thiserror::Error; #[derive(Error, Debug, PartialEq)] diff --git a/contracts/lockup/src/msgs.rs b/contracts/lockup/src/msgs.rs index f31e1ad..150c114 100644 --- a/contracts/lockup/src/msgs.rs +++ b/contracts/lockup/src/msgs.rs @@ -1,4 +1,3 @@ -use cosmwasm_std::Addr; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -23,7 +22,7 @@ pub enum QueryMsg { LocksByDenomAndAddressUnlockingAfter { denom: String, unlocking_after: u64, - address: Addr, + address: String, }, LocksByDenomBetween { denom: String, @@ -32,7 +31,7 @@ pub enum QueryMsg { }, LocksByDenomAndAddressBetween { denom: String, - address: Addr, + address: String, locked_before: u64, unlocking_after: u64, }, diff --git a/contracts/lockup/src/state.rs b/contracts/lockup/src/state.rs index 8409fc0..bd822c5 100644 --- a/contracts/lockup/src/state.rs +++ b/contracts/lockup/src/state.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Addr, Coin}; +use cosmwasm_std::Coin; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, MultiIndex}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -10,7 +10,7 @@ pub const LOCKS_ID: Item = Item::new("locks_id"); pub struct Lock { pub id: u64, pub coin: Coin, - pub owner: Addr, + pub owner: String, pub duration_blocks: u64, pub start_block: u64, pub end_block: u64, @@ -19,9 +19,9 @@ pub struct Lock { pub struct LockIndexes<'a> { pub denom_end: MultiIndex<'a, (String, u64), Lock, u64>, - pub addr_denom_end: MultiIndex<'a, (Addr, String, u64), Lock, u64>, + pub addr_denom_end: MultiIndex<'a, (String, String, u64), Lock, u64>, pub denom_start: MultiIndex<'a, (String, u64), Lock, u64>, - pub addr_denom_start: MultiIndex<'a, (Addr, String, u64), Lock, u64>, + pub addr_denom_start: MultiIndex<'a, (String, String, u64), Lock, u64>, } impl<'a> IndexList for LockIndexes<'a> { @@ -38,7 +38,7 @@ impl<'a> IndexList for LockIndexes<'a> { } } -pub fn locks<'a>() -> IndexedMap<'a, u64, Lock, LockIndexes<'a>> { +pub fn locks() -> IndexedMap> { let indexes = LockIndexes { addr_denom_end: MultiIndex::new( |_bz, lock: &Lock| -> (_, _, _) { @@ -75,5 +75,5 @@ pub fn locks<'a>() -> IndexedMap<'a, u64, Lock, LockIndexes<'a>> { ), }; - return IndexedMap::new("locks", indexes); + IndexedMap::new("locks", indexes) } diff --git a/contracts/nibi-stargate-perp/.cargo/config b/contracts/nibi-stargate-perp/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/nibi-stargate-perp/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/nibi-stargate-perp/.cargo/config.toml b/contracts/nibi-stargate-perp/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/nibi-stargate-perp/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/nibi-stargate-perp/Cargo.toml b/contracts/nibi-stargate-perp/Cargo.toml index 2a3941c..ecf0188 100644 --- a/contracts/nibi-stargate-perp/Cargo.toml +++ b/contracts/nibi-stargate-perp/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/NibiruChain/cw-nibiru" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] @@ -24,8 +23,9 @@ cw2 = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } nibiru-std = { workspace = true } +broker-bank = { workspace = true } [dev-dependencies] -cosmwasm-vm = "1.5.0" +cosmwasm-vm = "2.0.2" serde_json = "1.0.108" anyhow = { workspace = true } \ No newline at end of file diff --git a/contracts/nibi-stargate-perp/src/contract.rs b/contracts/nibi-stargate-perp/src/contract.rs index acf469a..8b7f512 100644 --- a/contracts/nibi-stargate-perp/src/contract.rs +++ b/contracts/nibi-stargate-perp/src/contract.rs @@ -1,7 +1,7 @@ +use broker_bank::contract::query_bank_balances; use cosmwasm_std::{ - entry_point, AllBalanceResponse, BankMsg, BankQuery, Binary, CosmosMsg, - Deps, DepsMut, Env, MessageInfo, QueryRequest, Response, StdError, - StdResult, + entry_point, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + Response, StdError, StdResult, }; use cw2::set_contract_version; @@ -204,7 +204,7 @@ pub fn execute( )); } let contract_address = env_ctx.contract.address; - let balances = query_contract_balance( + let balances: Vec = query_bank_balances( contract_address.to_string(), deps.as_ref(), )?; @@ -212,7 +212,7 @@ pub fn execute( // Send all funds to the specified recipient. let transfer_msg = BankMsg::Send { to_address: to.clone(), - amount: balances.amount, + amount: balances, }; Ok(Response::new().add_message(transfer_msg).add_attribute( event_key, @@ -277,23 +277,6 @@ fn check_can_execute(deps: Deps, sender: &str) -> StdResult { }) } -/// Query all contract balances or return an empty response -fn query_contract_balance( - contract_address: String, - deps: Deps, -) -> StdResult { - let query_result = - deps.querier - .query(&QueryRequest::Bank(BankQuery::AllBalances { - address: contract_address, - }))?; - let balances: AllBalanceResponse = match query_result { - Some(res) => res, - None => AllBalanceResponse::default(), - }; - Ok(balances) -} - #[cfg(test)] pub mod tests { use std::str::FromStr; @@ -460,7 +443,7 @@ pub mod tests { // Set up a mock querier with contract balance let balances: &[(&str, &[Coin])] = - &[(contract_address.as_str(), &[Coin::new(100, "token")])]; + &[(contract_address.as_str(), &[Coin::new(100u128, "token")])]; let querier = testing::MockQuerier::new(balances); deps.querier = querier; @@ -479,7 +462,7 @@ pub mod tests { // claim happy / partial TestCaseExecClaim { exec_msg: ExecuteMsg::Claim { - funds: Some(Coin::new(50, "token")), + funds: Some(Coin::new(50u128, "token")), claim_all: None, to: to_address.clone(), }, @@ -518,7 +501,7 @@ pub mod tests { // Set up a mock querier with contract balance let balances: &[(&str, &[Coin])] = - &[(contract_address.as_str(), &[Coin::new(100, "token")])]; + &[(contract_address.as_str(), &[Coin::new(100u128, "token")])]; let querier = testing::MockQuerier::new(balances); deps.querier = querier; diff --git a/contracts/nibi-stargate/.cargo/config b/contracts/nibi-stargate/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/nibi-stargate/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/nibi-stargate/.cargo/config.toml b/contracts/nibi-stargate/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/nibi-stargate/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/nibi-stargate/Cargo.toml b/contracts/nibi-stargate/Cargo.toml index f6c689d..6d0f27d 100644 --- a/contracts/nibi-stargate/Cargo.toml +++ b/contracts/nibi-stargate/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/nibi-stargate/src/bin/schema.rs b/contracts/nibi-stargate/src/bin/schema.rs new file mode 100644 index 0000000..9cdac7f --- /dev/null +++ b/contracts/nibi-stargate/src/bin/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use nibi_stargate::msgs::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/nibi-stargate/src/contract.rs b/contracts/nibi-stargate/src/contract.rs index 9cfeee7..ed94fe9 100644 --- a/contracts/nibi-stargate/src/contract.rs +++ b/contracts/nibi-stargate/src/contract.rs @@ -54,9 +54,9 @@ pub fn execute( let denom_parts: Vec<&str> = coin.denom.split('/').collect(); if denom_parts.len() != 3 { - return Err(StdError::GenericErr { - msg: "invalid denom input".to_string(), - } + return Err(StdError::generic_err( + "invalid denom input".to_string(), + ) .into()); } diff --git a/contracts/nibi-stargate/src/error.rs b/contracts/nibi-stargate/src/error.rs index 6e23521..a2f9599 100644 --- a/contracts/nibi-stargate/src/error.rs +++ b/contracts/nibi-stargate/src/error.rs @@ -1,7 +1,4 @@ use cosmwasm_std::StdError; -#[cfg(feature = "backtraces")] -use std::backtrace::Backtrace; - use thiserror::Error; #[derive(Error, Debug, PartialEq)] diff --git a/contracts/nibi-stargate/src/msgs.rs b/contracts/nibi-stargate/src/msgs.rs index f0b1c75..c7afb8c 100644 --- a/contracts/nibi-stargate/src/msgs.rs +++ b/contracts/nibi-stargate/src/msgs.rs @@ -13,5 +13,6 @@ pub enum ExecuteMsg { ChangeAdmin { denom: String, new_admin: String }, } +#[derive(cosmwasm_schema::QueryResponses)] #[cw_serde] pub enum QueryMsg {} diff --git a/contracts/nusd-valuator/.cargo/config b/contracts/nusd-valuator/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/nusd-valuator/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/nusd-valuator/.cargo/config.toml b/contracts/nusd-valuator/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/nusd-valuator/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/nusd-valuator/Cargo.toml b/contracts/nusd-valuator/Cargo.toml index e2fa7cc..09dbe8f 100644 --- a/contracts/nusd-valuator/Cargo.toml +++ b/contracts/nusd-valuator/Cargo.toml @@ -10,9 +10,8 @@ repository = "https://github.com/NibiruChain/cw-nibiru" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports -# library = [] +library = [] [dependencies] cosmwasm-std = { workspace = true } @@ -24,5 +23,5 @@ thiserror = { workspace = true } nibiru-std = { workspace = true } cw2 = { workspace = true } serde_json = { workspace = true } -cw-ownable = { workspace = true } +nibiru-ownable = { workspace = true } anyhow = { workspace = true } \ No newline at end of file diff --git a/contracts/nusd-valuator/src/contract.rs b/contracts/nusd-valuator/src/contract.rs index 6ab1cab..af05d7b 100644 --- a/contracts/nusd-valuator/src/contract.rs +++ b/contracts/nusd-valuator/src/contract.rs @@ -20,7 +20,7 @@ pub fn execute( ) -> Result { match msg { ExecuteMsg::ChangeDenom { from, to } => { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; // "from" should be within the list of accepted denoms let mut denom_set = ACCEPTED_DENOMS.load(deps.storage)?; @@ -45,7 +45,7 @@ pub fn execute( Ok(Response::default().add_event(event)) } ExecuteMsg::AddDenom { denom } => { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let mut denom_set = ACCEPTED_DENOMS.load(deps.storage)?; if denom_set.contains(&denom) { @@ -63,7 +63,7 @@ pub fn execute( } ExecuteMsg::RemoveDenom { denom } => { - cw_ownable::assert_owner(deps.storage, &info.sender)?; + nibiru_ownable::assert_owner(deps.storage, info.sender.as_str())?; let mut denom_set = ACCEPTED_DENOMS.load(deps.storage)?; let was_present = denom_set.remove(&denom); if !was_present { @@ -91,10 +91,14 @@ fn execute_update_ownership( deps: DepsMut, env: Env, info: MessageInfo, - action: cw_ownable::Action, -) -> Result { - let ownership = - cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + action: nibiru_ownable::Action, +) -> Result { + let ownership = nibiru_ownable::update_ownership( + deps, + &env.block, + info.sender.as_str(), + action, + )?; Ok(Response::new().add_attributes(ownership.into_attributes())) } @@ -138,7 +142,7 @@ pub fn instantiate( format!("crates.io:{CONTRACT_NAME}"), CONTRACT_VERSION, )?; - cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; + nibiru_ownable::initialize_owner(deps.storage, Some(&msg.owner))?; ACCEPTED_DENOMS.save(deps.storage, &msg.accepted_denoms)?; Ok(Response::default()) } diff --git a/contracts/nusd-valuator/src/error.rs b/contracts/nusd-valuator/src/error.rs index fdd291e..f675c9f 100644 --- a/contracts/nusd-valuator/src/error.rs +++ b/contracts/nusd-valuator/src/error.rs @@ -12,7 +12,7 @@ pub enum ContractError { SerdeJson(String), #[error("{0}")] - Ownership(#[from] cw_ownable::OwnershipError), + Ownership(#[from] nibiru_ownable::OwnershipError), // #[error("serde_json error: {err:?}")] // SerdeJson { err: serde_json::error::Error }, diff --git a/contracts/nusd-valuator/src/msgs.rs b/contracts/nusd-valuator/src/msgs.rs index df53807..1009a3c 100644 --- a/contracts/nusd-valuator/src/msgs.rs +++ b/contracts/nusd-valuator/src/msgs.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use cosmwasm_schema::cw_serde; use cosmwasm_std as cw; -#[cw_ownable::cw_ownable_query] +#[nibiru_ownable::ownable_query] #[cw_serde] #[derive(cosmwasm_schema::QueryResponses)] pub enum QueryMsg { @@ -30,7 +30,7 @@ pub enum QueryMsg { RedeemableChoices { redeem_amount: cw::Uint128 }, } -#[cw_ownable::cw_ownable_execute] +#[nibiru_ownable::ownable_execute] #[cw_serde] pub enum ExecuteMsg { /// Change one denom in the "ACCEPTED_DENOMS" set to another one in-place. diff --git a/contracts/nusd-valuator/src/queries.rs b/contracts/nusd-valuator/src/queries.rs index cd78957..fc14a98 100644 --- a/contracts/nusd-valuator/src/queries.rs +++ b/contracts/nusd-valuator/src/queries.rs @@ -27,7 +27,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { to_json_binary(&query_redeemable_choices(deps, redeem_amount)?) } QueryMsg::Ownership {} => { - to_json_binary(&cw_ownable::get_ownership(deps.storage)?) + to_json_binary(&nibiru_ownable::get_ownership(deps.storage)?) } } } diff --git a/contracts/pricefeed/.cargo/config b/contracts/pricefeed/.cargo/config deleted file mode 100644 index b613a59..0000000 --- a/contracts/pricefeed/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/contracts/pricefeed/.cargo/config.toml b/contracts/pricefeed/.cargo/config.toml new file mode 100644 index 0000000..051a969 --- /dev/null +++ b/contracts/pricefeed/.cargo/config.toml @@ -0,0 +1,9 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +schema = "run --bin schema" + +# OLDER: +# wasm = "build --release --target wasm32-unknown-unknown" +# wasm-debug = "build --target wasm32-unknown-unknown" +# schema = "run --example schema" \ No newline at end of file diff --git a/contracts/pricefeed/Cargo.toml b/contracts/pricefeed/Cargo.toml index 8ab05fe..ec82feb 100644 --- a/contracts/pricefeed/Cargo.toml +++ b/contracts/pricefeed/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/contracts/pricefeed/src/error.rs b/contracts/pricefeed/src/error.rs index 355de1e..16e6006 100644 --- a/contracts/pricefeed/src/error.rs +++ b/contracts/pricefeed/src/error.rs @@ -1,7 +1,4 @@ use cosmwasm_std::{Addr, StdError}; -#[cfg(feature = "backtraces")] -use std::backtrace::Backtrace; - use thiserror::Error; #[derive(Error, Debug, PartialEq)] diff --git a/nibiru-std/Cargo.toml b/nibiru-std/Cargo.toml index 21a4fe2..39e8d83 100644 --- a/nibiru-std/Cargo.toml +++ b/nibiru-std/Cargo.toml @@ -1,18 +1,16 @@ [package] name = "nibiru-std" -version = "0.0.5" +version = { workspace = true } edition = "2021" description = "Nibiru Chain standard library for CosmWasm smart contracts" authors = ["Unique Divine "] documentation = "https://docs.rs/nibiru-std" -homepage = "https://github.com/NibiruChain/cw-nibiru" -repository = "https://github.com/NibiruChain/cw-nibiru" +homepage = { workspace = true } +repository = { workspace = true } license-file = "LICENSE" -# license = "MIT" # only one of license, license-file is needed. [features] -backtraces = ["cosmwasm-std/backtraces"] default = [] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/core-controller/Cargo.toml b/packages/core-controller/Cargo.toml index 0d851b9..c214419 100644 --- a/packages/core-controller/Cargo.toml +++ b/packages/core-controller/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/NibiruChain/cw-nibiru" crate-type = ["cdylib", "rlib"] [features] -backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] diff --git a/packages/core-controller/src/contract.rs b/packages/core-controller/src/contract.rs index 03eb61a..784d805 100644 --- a/packages/core-controller/src/contract.rs +++ b/packages/core-controller/src/contract.rs @@ -134,9 +134,8 @@ pub fn execute( ExecuteMsg::AddMember { address } => { check_admin(check)?; - let api = deps.api; - let addr = api.addr_validate(address.as_str()).unwrap(); - whitelist.members.insert(addr.into_string()); + let addr = address.as_str(); + whitelist.members.insert(addr.to_string()); WHITELIST.save(deps.storage, &whitelist)?; let res = Response::new().add_attributes(vec![ @@ -160,9 +159,8 @@ pub fn execute( ExecuteMsg::ChangeAdmin { address } => { check_admin(check)?; - let api = deps.api; - let new_admin = api.addr_validate(address.as_str()).unwrap(); - whitelist.admin = new_admin.clone().into_string(); + let new_admin = address.as_str(); + whitelist.admin = new_admin.to_string(); whitelist.members.insert(new_admin.to_string()); WHITELIST.save(deps.storage, &whitelist)?; diff --git a/packages/cw-address-like/Cargo.toml b/packages/cw-address-like/Cargo.toml new file mode 100644 index 0000000..51e2abf --- /dev/null +++ b/packages/cw-address-like/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cw-address-like" +version = "2.0.0" + description = "A trait that marks unchecked or checked CosmWasm address strings" +authors = ["larry "] +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } + +[lib] +doctest = false # disable doc tests + +[dependencies] +cosmwasm-std = { workspace = true } \ No newline at end of file diff --git a/packages/cw-address-like/README.md b/packages/cw-address-like/README.md new file mode 100644 index 0000000..c6acd00 --- /dev/null +++ b/packages/cw-address-like/README.md @@ -0,0 +1,69 @@ +# CW Address Like + +This crate provides an trait `AddressLike`, which marks types that can be used as addresses in CosmWasm, namely `String` and `cosmwasm_std::Addr`. + +## Background + +In CosmWasm, there are two types that are typically used to represent addresses: + +- `String` - Represents an _unverified_ address, which are used in contract APIs, i.e. messages and query responses. +- `cosmwasm_std::Addr` - Represents an _verified_ address, used in contract internal logics. + +When a contract receives an address (as a `String`) from a message, it must not simply assume it is valid. Instead, it should use the `deps.api.addr_validate` method to verify it, which returns an `Addr`. The contract can then use the `Addr` in its business logics or save it in storage. + +Similarly, the contract should also converts `Addr`s back to `String`s when returning them in query responses. + +### The problem + +A problem arises when _we want to define a struct or enum that is to be used in both the API and internal logics._ For example, consider a contract that saves a "config" in its storage, which uses an `Addr` inside to represent the address of the contract's owner, while also providing a query method for the config, which uses a `String`. + +In such cases, developers may either define two types, one for each case: + +```rust +struct Config { + pub owner: Addr, +} + +struct ConfigResponse { + pub owner: String, +} +``` + +This approach works, but is somewhat cumbersome, especially when the config contains more fields. + +Another approach is to define a single type that contains a generic: + +```rust +struct Config { + pub owner: T, +} +``` + +Then use `Config` in the API and `Config` in internal logics. + +The main drawback of this approach is there's no restriction on what `T` can be. It is theoretically possible to plug any type in as `T` here, not limited to `String` and `Addr`. + +## How to use + +In this crate we provide an `AddressLike` trait, which is defined simply as: + +```rust +pub trait AddressLike {} + +impl AddressLike for Addr {} +impl AddressLike for String {} +``` + +The developer can then define their type as: + +```rust +struct Config { + pub owner: T, +} +``` + +This restricts that only `String` and `Addr` can be used as `T`. + +## License + +Contents of this crate at or prior to version `1.0.3` are published under [GNU Affero General Public License v3](https://github.com/steak-enjoyers/cw-plus-plus/blob/9c8fcf1c95b74dd415caf5602068c558e9d16ecc/LICENSE) or later; contents after the said version are published under [Apache-2.0](../../LICENSE) license. diff --git a/packages/cw-address-like/src/lib.rs b/packages/cw-address-like/src/lib.rs new file mode 100644 index 0000000..bfc4071 --- /dev/null +++ b/packages/cw-address-like/src/lib.rs @@ -0,0 +1,20 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +use std::{ + fmt::{Debug, Display}, + hash::Hash, +}; + +/// Marks either `String` or `cosmwasm_std::Addr`. +/// +/// String is used in unverified types, such as messages and query responses. +/// Addr is used in verified types, which are to be stored in blockchain state. +/// +/// This trait is intended to be used as a generic in type definitions. +pub trait AddressLike: + Clone + Debug + Display + PartialEq + Eq + PartialOrd + Ord + Hash +{ +} + +impl AddressLike for String {} +impl AddressLike for cosmwasm_std::Addr {} diff --git a/packages/easy-addr/Cargo.toml b/packages/easy-addr/Cargo.toml new file mode 100644 index 0000000..e7801ff --- /dev/null +++ b/packages/easy-addr/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "easy-addr" +version.workspace = true +edition = "2021" +publish = false + +[lib] +proc-macro = true + +[dependencies] +cosmwasm-std = { workspace = true } +proc-macro2 = "1" +quote = "1" +syn = { version = "1.0.6", features = ["full", "printing", "extra-traits"] } \ No newline at end of file diff --git a/packages/easy-addr/src/lib.rs b/packages/easy-addr/src/lib.rs new file mode 100644 index 0000000..385d24a --- /dev/null +++ b/packages/easy-addr/src/lib.rs @@ -0,0 +1,15 @@ +use cosmwasm_std::testing::mock_dependencies; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +#[proc_macro] +pub fn addr(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as syn::LitStr).value(); + let addr = mock_dependencies() + .api + .addr_make(input.as_str()) + .to_string(); + TokenStream::from(quote! {#addr}) +} diff --git a/packages/nibiru-ownable/Cargo.toml b/packages/nibiru-ownable/Cargo.toml new file mode 100644 index 0000000..74b58da --- /dev/null +++ b/packages/nibiru-ownable/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "nibiru-ownable" +version = { workspace = true } +description = "Utility for single-party ownership of CosmWasm smart contracts" +authors = ["larry ", "Unique Divine "] +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +# license = { workspace = true } +# keywords = { workspace = true } + +[lib] +doctest = false # disable doc tests + +[dependencies] +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +cw-address-like = { workspace = true } +ownable-derive = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +thiserror = { workspace = true } \ No newline at end of file diff --git a/packages/nibiru-ownable/README.md b/packages/nibiru-ownable/README.md new file mode 100644 index 0000000..8a8b8c2 --- /dev/null +++ b/packages/nibiru-ownable/README.md @@ -0,0 +1,128 @@ +# CW Ownable + +Utility for controlling ownership of [CosmWasm](https://github.com/CosmWasm/cosmwasm) smart contracts. + +## How to use + +Initialize the owner during instantiation using the `initialize_owner` method provided by this crate: + +```rust +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response}; +use nibiru_ownable::OwnershipError; + +#[entry_point] +pub fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMsg, +) -> Result, OwnershipError> { + nibiru_ownable::initialize_owner(deps.storage, deps.api, msg.owner.as_deref())?; + Ok(Response::new()) +} +``` + +Use the `#[ownable_execute]` macro to extend your execute message: + +```rust +use cosmwasm_schema::cw_serde; +use nibiru_ownable::ownable_execute; + +#[ownable_execute] +#[cw_serde] +enum ExecuteMsg { + Foo {}, + Bar {}, +} +``` + +The macro inserts a new variant, `UpdateOwnership` to the enum: + +```rust +#[cw_serde] +enum ExecuteMsg { + UpdateOwnership(nibiru_ownable::Action), + Foo {}, + Bar {}, +} +``` + +Where `Action` can be one of three: + +- Propose to transfer the contract's ownership to another account +- Accept the proposed ownership transfer +- Renounce the ownership, permanently setting the contract's owner to vacant + +Handle the messages using the `update_ownership` function provided by this crate: + +```rust +use cosmwasm_std::{entry_point, DepsMut, Env, MessageInfo, Response}; +use nibiru_ownable::{cw_serde, update_ownership, OwnershipError}; + +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::UpdateOwnership(action) => { + update_ownership(deps, &env.block, &info.sender, action)?; + } + _ => unimplemneted!(), + } + Ok(Response::new()) +} +``` + +Use the `#[ownable_query]` macro to extend your query message: + +```rust +use cosmwasm_schema::{cw_serde, QueryResponses}; +use nibiru_ownable::ownable_query; + +#[ownable_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(FooResponse)] + Foo {}, + #[returns(BarResponse)] + Bar {}, +} +``` + +The macro inserts a new variant, `Ownership`: + +```rust +#[cw_serde] +#[derive(QueryResponses)] +enum QueryMsg { + #[returns(Ownership)] + Ownership {}, + #[returns(FooResponse)] + Foo {}, + #[returns(BarResponse)] + Bar {}, +} +``` + +Handle the message using the `get_ownership` function provided by this crate: + +```rust +use cosmwasm_std::{entry_point, Deps, Env, Binary}; +use nibiru_ownable::get_ownership; + +#[entry_point] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Ownership {} => to_binary(&get_ownership(deps.storage)?), + _ => unimplemented!(), + } +} +``` + +## License + +Contents of this crate at or prior to version `0.5.0` are published under [GNU Affero General Public License v3](https://github.com/steak-enjoyers/cw-plus-plus/blob/9c8fcf1c95b74dd415caf5602068c558e9d16ecc/LICENSE) or later; contents after the said version are published under [Apache-2.0](../../LICENSE) license. \ No newline at end of file diff --git a/packages/nibiru-ownable/derive/Cargo.toml b/packages/nibiru-ownable/derive/Cargo.toml new file mode 100644 index 0000000..466bb9c --- /dev/null +++ b/packages/nibiru-ownable/derive/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "ownable-derive" +version = "0.6.0" +description = "Macros for generating code used by the `nibiru-ownable` crate" +authors = ["larry ", "Unique Divine "] +# edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" # only one of license, license-file is needed. + +[lib] +doctest = true # disable doc tests +proc-macro = true + +[dependencies] +proc-macro2 = { workspace = true } +quote = { workspace = true } +syn = { workspace = true } + +[dev-dependencies] +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +nibiru-ownable = { workspace = true } \ No newline at end of file diff --git a/packages/nibiru-ownable/derive/README.md b/packages/nibiru-ownable/derive/README.md new file mode 100644 index 0000000..c0b4295 --- /dev/null +++ b/packages/nibiru-ownable/derive/README.md @@ -0,0 +1,7 @@ +# CW Ownable Derive + +Macros for generating code used by the [`cw-ownable`](https://crates.io/crates/cw-ownable) crate. + +## License + +Contents of this crate at or prior to version `0.5.0` are published under [GNU Affero General Public License v3](https://github.com/steak-enjoyers/cw-plus-plus/blob/9c8fcf1c95b74dd415caf5602068c558e9d16ecc/LICENSE) or later; contents after the said version are published under [Apache-2.0](../../../LICENSE) license. diff --git a/packages/nibiru-ownable/derive/src/lib.rs b/packages/nibiru-ownable/derive/src/lib.rs new file mode 100644 index 0000000..5f2d161 --- /dev/null +++ b/packages/nibiru-ownable/derive/src/lib.rs @@ -0,0 +1,186 @@ +extern crate proc_macro; +extern crate quote; +extern crate syn; +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, AttributeArgs, DataEnum, DeriveInput}; + +/// Merges the variants of two enums. +/// +/// Adapted from DAO DAO: +/// https://github.com/DA0-DA0/dao-contracts/blob/74bd3881fdd86829e5e8b132b9952dd64f2d0737/packages/dao-macros/src/lib.rs#L9 +fn merge_variants( + metadata: TokenStream, + left: TokenStream, + right: TokenStream, +) -> TokenStream { + use syn::Data::Enum; + + // parse metadata + let args = parse_macro_input!(metadata as AttributeArgs); + if let Some(first_arg) = args.first() { + return syn::Error::new_spanned(first_arg, "macro takes no arguments") + .to_compile_error() + .into(); + } + + // parse the left enum + let mut left: DeriveInput = parse_macro_input!(left); + let Enum(DataEnum { variants, .. }) = &mut left.data else { + return syn::Error::new( + left.ident.span(), + "only enums can accept variants", + ) + .to_compile_error() + .into(); + }; + + // parse the right enum + let right: DeriveInput = parse_macro_input!(right); + let Enum(DataEnum { + variants: to_add, .. + }) = right.data + else { + return syn::Error::new( + left.ident.span(), + "only enums can provide variants", + ) + .to_compile_error() + .into(); + }; + + // insert variants from the right to the left + variants.extend(to_add); + + quote! { #left }.into() +} + +/// Append ownership-related execute message variant(s) to an enum. +/// +/// For example, apply the `ownable_execute` macro to the following enum: +/// +/// ```rust +/// extern crate cosmwasm_schema; // not to be copied +/// extern crate nibiru_ownable; // not to be copied +/// use cosmwasm_schema::cw_serde; +/// use nibiru_ownable::ownable_execute; +/// +/// #[ownable_execute] +/// #[cw_serde] +/// enum ExecuteMsg { +/// Foo {}, +/// Bar {}, +/// } +/// ``` +/// +/// Is equivalent to: +/// +/// ```rust +/// extern crate cosmwasm_schema; // not to be copied +/// extern crate nibiru_ownable; // not to be copied +/// use cosmwasm_schema::cw_serde; +/// use nibiru_ownable::Action; +/// +/// #[cw_serde] +/// enum ExecuteMsg { +/// UpdateOwnership(Action), +/// Foo {}, +/// Bar {}, +/// } +/// +/// let _msg = ExecuteMsg::Foo{}; +/// ``` +/// +/// Note: `#[ownable_execute]` must be applied _before_ `#[cw_serde]`. +#[proc_macro_attribute] +pub fn ownable_execute( + metadata: TokenStream, + input: TokenStream, +) -> TokenStream { + merge_variants( + metadata, + input, + quote! { + enum Right { + /// Update the contract's ownership. The `action` to be provided + /// can be either to propose transferring ownership to an account, + /// accept a pending ownership transfer, or renounce the ownership + /// permanently. + UpdateOwnership(::nibiru_ownable::Action), + } + } + .into(), + ) +} + +/// Append ownership-related query message variant(s) to an enum. +/// +/// For example, apply the `ownable_query` macro to the following enum: +/// +/// ```rust +/// extern crate cosmwasm_schema; // not to be copied +/// extern crate nibiru_ownable; // not to be copied +/// use cosmwasm_schema::{cw_serde, QueryResponses}; +/// use nibiru_ownable::ownable_query; +/// +/// #[ownable_query] +/// #[cw_serde] +/// #[derive(QueryResponses)] +/// enum QueryMsg { +/// #[returns(FooResponse)] +/// Foo {}, +/// #[returns(BarResponse)] +/// Bar {}, +/// } +/// +/// #[cw_serde] +/// pub struct FooResponse {} +/// #[cw_serde] +/// pub struct BarResponse {} +/// +/// let _msg = QueryMsg::Foo{}; +/// ``` +/// +/// Is equivalent to: +/// +/// ```rust +/// extern crate cosmwasm_schema; // not to be copied +/// extern crate nibiru_ownable; // not to be copied +/// use cosmwasm_schema::{cw_serde, QueryResponses}; +/// use nibiru_ownable::Ownership; +/// +/// #[cw_serde] +/// #[derive(QueryResponses)] +/// enum QueryMsg { +/// #[returns(Ownership)] +/// Ownership {}, +/// #[returns(FooResponse)] +/// Foo {}, +/// #[returns(BarResponse)] +/// Bar {}, +/// } +/// +/// #[cw_serde] +/// pub struct FooResponse {} +/// #[cw_serde] +/// pub struct BarResponse {} +/// +/// let _msg = QueryMsg::Bar{}; +/// ``` +/// +/// Note: `#[ownable_query]` must be applied _before_ `#[cw_serde]`. +#[proc_macro_attribute] +pub fn ownable_query(metadata: TokenStream, input: TokenStream) -> TokenStream { + merge_variants( + metadata, + input, + quote! { + enum Right { + /// Query the contract's ownership information + #[returns(::nibiru_ownable::Ownership)] + Ownership {}, + } + } + .into(), + ) +} diff --git a/packages/nibiru-ownable/src/lib.rs b/packages/nibiru-ownable/src/lib.rs new file mode 100644 index 0000000..2d52625 --- /dev/null +++ b/packages/nibiru-ownable/src/lib.rs @@ -0,0 +1,588 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +use std::fmt::Display; + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ + Attribute, BlockInfo, DepsMut, StdError, StdResult, Storage, +}; +use cw_address_like::AddressLike; +use cw_storage_plus::Item; + +// re-export the proc macros and the Expiration class +pub use cw_utils::Expiration; +pub use ownable_derive::{ownable_execute, ownable_query}; + +/// The contract's ownership info +#[cw_serde] +pub struct Ownership { + /// The contract's current owner. + /// `None` if the ownership has been renounced. + pub owner: Option, + + /// The account who has been proposed to take over the ownership. + /// `None` if there isn't a pending ownership transfer. + pub pending_owner: Option, + + /// The deadline for the pending owner to accept the ownership. + /// `None` if there isn't a pending ownership transfer, or if a transfer + /// exists and it doesn't have a deadline. + pub pending_expiry: Option, +} + +/// Actions that can be taken to alter the contract's ownership +#[cw_serde] +pub enum Action { + /// Propose to transfer the contract's ownership to another account, + /// optionally with an expiry time. + /// + /// Can only be called by the contract's current owner. + /// + /// Any existing pending ownership transfer is overwritten. + TransferOwnership { + new_owner: String, + expiry: Option, + }, + + /// Accept the pending ownership transfer. + /// + /// Can only be called by the pending owner. + AcceptOwnership, + + /// Give up the contract's ownership and the possibility of appointing + /// a new owner. + /// + /// Can only be invoked by the contract's current owner. + /// + /// Any existing pending ownership transfer is canceled. + RenounceOwnership, +} + +/// Errors associated with the contract's ownership +#[derive(thiserror::Error, Debug, PartialEq)] +pub enum OwnershipError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Contract ownership has been renounced")] + NoOwner, + + #[error("Caller is not the contract's current owner")] + NotOwner, + + #[error("Caller is not the contract's pending owner")] + NotPendingOwner, + + #[error("There isn't a pending ownership transfer")] + TransferNotFound, + + #[error("A pending ownership transfer exists but it has expired")] + TransferExpired, +} + +/// Storage constant for the contract's ownership +const OWNERSHIP: Item> = Item::new("ownership"); + +/// Set the given address as the contract owner. +/// +/// This function is only intended to be used only during contract instantiation. +pub fn initialize_owner( + storage: &mut dyn Storage, + owner: Option<&str>, +) -> StdResult> { + let ownership = Ownership { + owner: owner.map(String::from), + pending_owner: None, + pending_expiry: None, + }; + OWNERSHIP.save(storage, &ownership)?; + Ok(ownership) +} + +/// Return Ok(true) if the contract has an owner and it's the given address. +/// Return Ok(false) if the contract doesn't have an owner, of if it does but +/// it's not the given address. +/// Return Err if fails to load ownership info from storage. +pub fn is_owner(store: &dyn Storage, addr: &str) -> StdResult { + let ownership = OWNERSHIP.load(store)?; + + if let Some(owner) = ownership.owner { + if addr == owner { + return Ok(true); + } + } + + Ok(false) +} + +/// Assert that an account is the contract's current owner. +pub fn assert_owner( + store: &dyn Storage, + sender: &str, +) -> Result<(), OwnershipError> { + let ownership = OWNERSHIP.load(store)?; + check_owner(&ownership, sender) +} + +/// Assert that an account is the contract's current owner. +fn check_owner( + ownership: &Ownership, + sender: &str, +) -> Result<(), OwnershipError> { + // the contract must have an owner + let Some(current_owner) = &ownership.owner else { + return Err(OwnershipError::NoOwner); + }; + + // the sender must be the current owner + if sender != current_owner { + return Err(OwnershipError::NotOwner); + } + + Ok(()) +} + +/// Update the contract's ownership info based on the given action. +/// Return the updated ownership. +pub fn update_ownership( + deps: DepsMut, + block: &BlockInfo, + sender: &str, + action: Action, +) -> Result, OwnershipError> { + match action { + Action::TransferOwnership { new_owner, expiry } => { + transfer_ownership(deps, sender, &new_owner, expiry) + } + Action::AcceptOwnership => accept_ownership(deps.storage, block, sender), + Action::RenounceOwnership => renounce_ownership(deps.storage, sender), + } +} + +/// Get the current ownership value. +pub fn get_ownership(storage: &dyn Storage) -> StdResult> { + OWNERSHIP.load(storage) +} + +impl Ownership { + /// Serializes the current ownership state as attributes which may + /// be used in a message response. Serialization is done according + /// to the std::fmt::Display implementation for `T` and + /// `cosmwasm_std::Expiration` (for `pending_expiry`). If an + /// ownership field has no value, `"none"` will be serialized. + /// + /// Attribute keys used: + /// - owner + /// - pending_owner + /// - pending_expiry + /// + /// Callers should take care not to use these keys elsewhere + /// in their response as CosmWasm will override reused attribute + /// keys. + /// + /// # Example + /// + /// ```rust + /// use cw_utils::Expiration; + /// + /// assert_eq!( + /// Ownership { + /// owner: Some("blue"), + /// pending_owner: None, + /// pending_expiry: Some(Expiration::Never {}) + /// } + /// .into_attributes(), + /// vec![ + /// Attribute::new("owner", "blue"), + /// Attribute::new("pending_owner", "none"), + /// Attribute::new("pending_expiry", "expiration: never") + /// ], + /// ) + /// ``` + pub fn into_attributes(self) -> Vec { + vec![ + Attribute::new("owner", none_or(self.owner.as_ref())), + Attribute::new( + "pending_owner", + none_or(self.pending_owner.as_ref()), + ), + Attribute::new( + "pending_expiry", + none_or(self.pending_expiry.as_ref()), + ), + ] + } +} + +fn none_or(or: Option<&T>) -> String { + or.map_or_else(|| "none".to_string(), |or| or.to_string()) +} + +/// Propose to transfer the contract's ownership to the given address, with an +/// optional deadline. +fn transfer_ownership( + deps: DepsMut, + sender: &str, + new_owner: &str, + expiry: Option, +) -> Result, OwnershipError> { + OWNERSHIP.update(deps.storage, |ownership| { + // the contract must have an owner + check_owner(&ownership, sender)?; + + // NOTE: We don't validate the expiry, i.e. asserting it is later than + // the current block time. + // + // This is because if the owner submits an invalid expiry, it won't have + // any negative effect - it's just that the pending owner won't be able + // to accept the ownership. + // + // By not doing the check, we save a little bit of gas. + // + // To fix the erorr, the owner can simply invoke `transfer_ownership` + // again with the correct expiry and overwrite the invalid one. + Ok(Ownership { + pending_owner: Some(new_owner.to_string()), + pending_expiry: expiry, + ..ownership + }) + }) +} + +/// Accept a pending ownership transfer. +fn accept_ownership( + store: &mut dyn Storage, + block: &BlockInfo, + sender: &str, +) -> Result, OwnershipError> { + OWNERSHIP.update(store, |ownership| { + // there must be an existing ownership transfer + let Some(pending_owner) = &ownership.pending_owner else { + return Err(OwnershipError::TransferNotFound); + }; + + // the sender must be the pending owner + if sender != pending_owner { + return Err(OwnershipError::NotPendingOwner); + }; + + // if the transfer has a deadline, it must not have been reached + if let Some(expiry) = &ownership.pending_expiry { + if expiry.is_expired(block) { + return Err(OwnershipError::TransferExpired); + } + } + + Ok(Ownership { + owner: ownership.pending_owner, + pending_owner: None, + pending_expiry: None, + }) + }) +} + +/// Set the contract's ownership as vacant permanently. +fn renounce_ownership( + store: &mut dyn Storage, + sender: &str, +) -> Result, OwnershipError> { + OWNERSHIP.update(store, |ownership| { + check_owner(&ownership, sender)?; + + Ok(Ownership { + owner: None, + pending_owner: None, + pending_expiry: None, + }) + }) +} + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +#[cfg(test)] +mod tests { + use cosmwasm_std::{testing::mock_dependencies, Timestamp}; + + use super::*; + + fn mock_addresses() -> [String; 3] { + [ + String::from("larry"), + String::from("jake"), + String::from("pumpkin"), + ] + } + + fn mock_block_at_height(height: u64) -> BlockInfo { + BlockInfo { + height, + time: Timestamp::from_seconds(10000), + chain_id: "".into(), + } + } + + #[test] + fn initializing_ownership() { + let mut deps = mock_dependencies(); + let [larry, _, _] = mock_addresses(); + + let ownership = + initialize_owner(&mut deps.storage, Some(larry.as_str())).unwrap(); + + // ownership returned is same as ownership stored. + assert_eq!(ownership, OWNERSHIP.load(deps.as_ref().storage).unwrap()); + + assert_eq!( + ownership, + Ownership { + owner: Some(larry), + pending_owner: None, + pending_expiry: None, + }, + ); + } + + #[test] + fn initialize_ownership_no_owner() { + let mut deps = mock_dependencies(); + let ownership = initialize_owner(&mut deps.storage, None).unwrap(); + assert_eq!( + ownership, + Ownership { + owner: None, + pending_owner: None, + pending_expiry: None, + }, + ); + } + + #[test] + fn asserting_ownership() { + let mut deps = mock_dependencies(); + let [larry, jake, _] = mock_addresses(); + + // case 1. owner has not renounced + { + initialize_owner(&mut deps.storage, Some(larry.as_str())).unwrap(); + + let res = assert_owner(deps.as_ref().storage, &larry); + assert!(res.is_ok()); + + let res = assert_owner(deps.as_ref().storage, &jake); + assert_eq!(res.unwrap_err(), OwnershipError::NotOwner); + } + + // case 2. owner has renounced + { + renounce_ownership(deps.as_mut().storage, &larry).unwrap(); + + let res = assert_owner(deps.as_ref().storage, &larry); + assert_eq!(res.unwrap_err(), OwnershipError::NoOwner); + } + } + + #[test] + fn transferring_ownership() { + let mut deps = mock_dependencies(); + let [larry, jake, pumpkin] = mock_addresses(); + + initialize_owner(&mut deps.storage, Some(larry.as_str())).unwrap(); + + // non-owner cannot transfer ownership + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &jake, + Action::TransferOwnership { + new_owner: pumpkin.to_string(), + expiry: None, + }, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::NotOwner); + } + + // owner properly transfers ownership + { + let ownership = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &larry, + Action::TransferOwnership { + new_owner: pumpkin.to_string(), + expiry: Some(Expiration::AtHeight(42069)), + }, + ) + .unwrap(); + assert_eq!( + ownership, + Ownership { + owner: Some(larry), + pending_owner: Some(pumpkin), + pending_expiry: Some(Expiration::AtHeight(42069)), + }, + ); + + let saved_ownership = OWNERSHIP.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_ownership, ownership); + } + } + + #[test] + fn accepting_ownership() { + let mut deps = mock_dependencies(); + let [larry, jake, pumpkin] = mock_addresses(); + + initialize_owner(&mut deps.storage, Some(larry.as_str())).unwrap(); + + // cannot accept ownership when there isn't a pending ownership transfer + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &pumpkin, + Action::AcceptOwnership, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::TransferNotFound); + } + + transfer_ownership( + deps.as_mut(), + &larry, + pumpkin.as_str(), + Some(Expiration::AtHeight(42069)), + ) + .unwrap(); + + // non-pending owner cannot accept ownership + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &jake, + Action::AcceptOwnership, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::NotPendingOwner); + } + + // cannot accept ownership if deadline has passed + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(69420), + &pumpkin, + Action::AcceptOwnership, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::TransferExpired); + } + + // pending owner properly accepts ownership before deadline + { + let ownership = update_ownership( + deps.as_mut(), + &mock_block_at_height(10000), + &pumpkin, + Action::AcceptOwnership, + ) + .unwrap(); + assert_eq!( + ownership, + Ownership { + owner: Some(pumpkin), + pending_owner: None, + pending_expiry: None, + }, + ); + + let saved_ownership = OWNERSHIP.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_ownership, ownership); + } + } + + #[test] + fn renouncing_ownership() { + let mut deps = mock_dependencies(); + let [larry, jake, pumpkin] = mock_addresses(); + + let ownership = Ownership { + owner: Some(larry.clone()), + pending_owner: Some(pumpkin), + pending_expiry: None, + }; + OWNERSHIP.save(deps.as_mut().storage, &ownership).unwrap(); + + // non-owner cannot renounce + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &jake, + Action::RenounceOwnership, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::NotOwner); + } + + // owner properly renounces + { + let ownership = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &larry, + Action::RenounceOwnership, + ) + .unwrap(); + + // ownership returned is same as ownership stored. + assert_eq!( + ownership, + OWNERSHIP.load(deps.as_ref().storage).unwrap() + ); + + assert_eq!( + ownership, + Ownership { + owner: None, + pending_owner: None, + pending_expiry: None, + }, + ); + } + + // cannot renounce twice + { + let err = update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &larry, + Action::RenounceOwnership, + ) + .unwrap_err(); + assert_eq!(err, OwnershipError::NoOwner); + } + } + + #[test] + fn into_attributes_works() { + use cw_utils::Expiration; + assert_eq!( + Ownership { + owner: Some("blue".to_string()), + pending_owner: None, + pending_expiry: Some(Expiration::Never {}) + } + .into_attributes(), + vec![ + Attribute::new("owner", "blue"), + Attribute::new("pending_owner", "none"), + Attribute::new("pending_expiry", "expiration: never") + ], + ); + } +} diff --git a/packages/nibiru-ownable/tests/macro.rs b/packages/nibiru-ownable/tests/macro.rs new file mode 100644 index 0000000..0a55e05 --- /dev/null +++ b/packages/nibiru-ownable/tests/macro.rs @@ -0,0 +1,55 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use nibiru_ownable::{ownable_execute, ownable_query, Action}; + +#[ownable_execute] +#[cw_serde] +enum ExecuteMsg { + Foo, + Bar(u64), + Fuzz { buzz: String }, +} + +#[ownable_query] +#[cw_serde] +#[derive(QueryResponses)] +enum QueryMsg { + #[returns(String)] + Foo, + + #[returns(String)] + Bar(u64), + + #[returns(String)] + Fuzz { buzz: String }, +} + +#[test] +fn derive_execute_variants() { + let msg = ExecuteMsg::Foo; + + // If this compiles we have won. + match msg { + ExecuteMsg::UpdateOwnership(Action::TransferOwnership { + new_owner: _, + expiry: _, + }) + | ExecuteMsg::UpdateOwnership(Action::AcceptOwnership) + | ExecuteMsg::UpdateOwnership(Action::RenounceOwnership) + | ExecuteMsg::Foo + | ExecuteMsg::Bar(_) + | ExecuteMsg::Fuzz { .. } => "yay", + }; +} + +#[test] +fn derive_query_variants() { + let msg = QueryMsg::Foo; + + // If this compiles we have won. + match msg { + QueryMsg::Ownership {} + | QueryMsg::Foo + | QueryMsg::Bar(_) + | QueryMsg::Fuzz { .. } => "yay", + }; +}