From 3c55adb43d6630d77e57c09531607bf2394933df Mon Sep 17 00:00:00 2001 From: mr-t Date: Wed, 28 Feb 2024 20:27:37 +0100 Subject: [PATCH 1/4] move all logic to `OwnershipStore`. This way `cw-ownable` is still a singleton. But can be re-use e.g. by defining `CREATOR: OwnershipStore = OwnershipStore::new("creator")` --- Cargo.lock | 186 +++++++-------- Cargo.toml | 2 +- README.md | 2 +- packages/ownable/Cargo.toml | 2 +- packages/ownable/README.md | 10 + packages/ownable/derive/Cargo.toml | 2 +- packages/ownable/src/lib.rs | 363 +++++++++++++++++------------ 7 files changed, 319 insertions(+), 248 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e297e0..e6e3bc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,15 +15,15 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -31,6 +31,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "block-buffer" version = "0.9.0" @@ -49,6 +55,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" + [[package]] name = "byteorder" version = "1.4.3" @@ -69,11 +81,12 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-crypto" -version = "1.2.7" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb64554a91d6a9231127f4355d351130a0b94e663d5d9dc8b3a54ca17d83de49" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", + "ecdsa", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -82,18 +95,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.7" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0fb2ce09f41a3dae1a234d56a9988f9aff4c76441cd50ef1ee9a4f20415b028" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.7" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230e5d1cefae5331db8934763c81b9c871db6a2cd899056a5694fa71d292c815" +checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -104,9 +117,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.7" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43dadf7c23406cb28079d69e6cb922c9c29b9157b0fe887e3b79c783b7d4bcb8" +checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" dependencies = [ "proc-macro2", "quote", @@ -115,11 +128,13 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.7" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4337eef8dfaf8572fe6b6b415d6ec25f9308c7bb09f2da63789209fb131363be" +checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" dependencies = [ "base64", + "bech32", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -129,8 +144,8 @@ dependencies = [ "serde", "serde-json-wasm", "sha2 0.10.7", + "static_assertions", "thiserror", - "uint", ] [[package]] @@ -142,17 +157,11 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -209,7 +218,7 @@ dependencies = [ [[package]] name = "cw-ownable" -version = "0.5.1" +version = "0.6.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -222,7 +231,7 @@ dependencies = [ [[package]] name = "cw-ownable-derive" -version = "0.5.1" +version = "0.6.0" dependencies = [ "proc-macro2", "quote", @@ -251,9 +260,9 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -266,23 +275,24 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -315,6 +325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] @@ -327,14 +338,16 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -354,13 +367,12 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest 0.10.7", "ff", "generic-array", @@ -374,9 +386,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -396,6 +408,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -411,9 +424,9 @@ dependencies = [ [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -452,14 +465,16 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", + "once_cell", "sha2 0.10.7", + "signature", ] [[package]] @@ -482,9 +497,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -492,18 +507,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -525,13 +540,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] @@ -542,9 +556,9 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -554,9 +568,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -566,9 +580,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -580,37 +594,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.51", ] [[package]] @@ -661,9 +675,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -671,9 +685,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.6.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -704,9 +718,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" dependencies = [ "proc-macro2", "quote", @@ -715,22 +729,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.51", ] [[package]] @@ -739,18 +753,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-ident" version = "1.0.9" @@ -771,6 +773,6 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index f4de0d4..daa4d40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["cosmos", "cosmwasm"] cosmwasm-schema = "1.2" cosmwasm-std = "1.2" cw-address-like = { version = "1.0.4", path = "./packages/address-like" } -cw-ownable-derive = { version = "0.5.1", path = "./packages/ownable/derive" } +cw-ownable-derive = { version = "0.6.0", path = "./packages/ownable/derive" } cw-storage-plus = "1.1" cw-utils = "1.0" proc-macro2 = "1" diff --git a/README.md b/README.md index 26f3cd9..f6ad969 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A collection of [CosmWasm][1] utilities and helper libraries. | [cw-address-like][2] | v1.0.4 | A trait that marks unchecked or checked address strings | | [cw-item-set][3] | v0.7.1 | Set of non-duplicate items for storage | | [cw-optional-indexes][4] | v0.1.1 | Index types for `IndexedMap` where an item may or may not have an index | -| [cw-ownable][5] | v0.5.1 | Utility for controlling contract ownership | +| [cw-ownable][5] | v0.6.0 | Utility for controlling contract ownership | | [cw-paginate][6] | v0.2.1 | Helper function for interating maps | ## License diff --git a/packages/ownable/Cargo.toml b/packages/ownable/Cargo.toml index 3c3c857..8ba2654 100644 --- a/packages/ownable/Cargo.toml +++ b/packages/ownable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-ownable" -version = "0.5.1" +version = "0.6.0" description = "Utility for controlling ownership of CosmWasm smart contracts" authors = { workspace = true } edition = { workspace = true } diff --git a/packages/ownable/README.md b/packages/ownable/README.md index 710248d..19eab04 100644 --- a/packages/ownable/README.md +++ b/packages/ownable/README.md @@ -123,6 +123,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } ``` +You can use ownership for other purposes: + +```rust +use cw_ownable::OwnershipStore; + +pub const CREATOR: OwnershipStore = OwnershipStore::new("creator"); +``` + +`CREATOR` has all functions in place: `initialize_owner`, `is_owner`, `assert_owner`, and `get_ownership`. + ## 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/ownable/derive/Cargo.toml b/packages/ownable/derive/Cargo.toml index 102b30d..ee2ac22 100644 --- a/packages/ownable/derive/Cargo.toml +++ b/packages/ownable/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cw-ownable-derive" -version = "0.5.1" +version = "0.6.0" description = "Macros for generating code used by the `cw-ownable` crate" authors = { workspace = true } edition = { workspace = true } diff --git a/packages/ownable/src/lib.rs b/packages/ownable/src/lib.rs index 5e5981b..3dfb56e 100644 --- a/packages/ownable/src/lib.rs +++ b/packages/ownable/src/lib.rs @@ -28,6 +28,183 @@ pub struct Ownership { pub pending_expiry: Option, } +pub struct OwnershipStore<'a> { + pub item: Item<'a, Ownership>, +} + +impl<'a> OwnershipStore<'a> { + pub const fn new(key: &'a str) -> Self { + Self { + item: Item::new(key), + } + } + + /// Set the given address as the contract owner. + /// + /// This function is only intended to be used only during contract instantiation. + pub fn initialize_owner( + &self, + storage: &mut dyn Storage, + api: &dyn Api, + owner: Option<&str>, + ) -> StdResult> { + let ownership = Ownership { + owner: owner.map(|h| api.addr_validate(h)).transpose()?, + pending_owner: None, + pending_expiry: None, + }; + self.item.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(&self, store: &dyn Storage, addr: &Addr) -> StdResult { + let ownership = self.item.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(&self, store: &dyn Storage, sender: &Addr) -> Result<(), OwnershipError> { + let ownership = self.item.load(store)?; + self.check_owner(&ownership, sender) + } + + /// Assert that an account is the contract's current owner. + fn check_owner( + &self, + ownership: &Ownership, + sender: &Addr, + ) -> 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( + &self, + deps: DepsMut, + block: &BlockInfo, + sender: &Addr, + action: Action, + ) -> Result, OwnershipError> { + match action { + Action::TransferOwnership { + new_owner, + expiry, + } => self.transfer_ownership(deps, sender, &new_owner, expiry), + Action::AcceptOwnership => self.accept_ownership(deps.storage, block, sender), + Action::RenounceOwnership => self.renounce_ownership(deps.storage, sender), + } + } + + /// Get the current ownership value. + pub fn get_ownership(&self, storage: &dyn Storage) -> StdResult> { + self.item.load(storage) + } + + /// Propose to transfer the contract's ownership to the given address, with an + /// optional deadline. + fn transfer_ownership( + &self, + deps: DepsMut, + sender: &Addr, + new_owner: &str, + expiry: Option, + ) -> Result, OwnershipError> { + self.item.update(deps.storage, |ownership| { + // the contract must have an owner + self.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(deps.api.addr_validate(new_owner)?), + pending_expiry: expiry, + ..ownership + }) + }) + } + + /// Accept a pending ownership transfer. + fn accept_ownership( + &self, + store: &mut dyn Storage, + block: &BlockInfo, + sender: &Addr, + ) -> Result, OwnershipError> { + self.item.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( + &self, + store: &mut dyn Storage, + sender: &Addr, + ) -> Result, OwnershipError> { + self.item.update(store, |ownership| { + self.check_owner(&ownership, sender)?; + + Ok(Ownership { + owner: None, + pending_owner: None, + pending_expiry: None, + }) + }) + } +} + /// Actions that can be taken to alter the contract's ownership #[cw_serde] pub enum Action { @@ -79,7 +256,8 @@ pub enum OwnershipError { } /// Storage constant for the contract's ownership -const OWNERSHIP: Item> = Item::new("ownership"); +pub const OWNERSHIP_KEY: &str = "ownership"; +pub const OWNERSHIP: OwnershipStore = OwnershipStore::new(OWNERSHIP_KEY); /// Set the given address as the contract owner. /// @@ -89,13 +267,7 @@ pub fn initialize_owner( api: &dyn Api, owner: Option<&str>, ) -> StdResult> { - let ownership = Ownership { - owner: owner.map(|h| api.addr_validate(h)).transpose()?, - pending_owner: None, - pending_expiry: None, - }; - OWNERSHIP.save(storage, &ownership)?; - Ok(ownership) + OWNERSHIP.initialize_owner(storage, api, owner) } /// Return Ok(true) if the contract has an owner and it's the given address. @@ -103,36 +275,12 @@ pub fn initialize_owner( /// it's not the given address. /// Return Err if fails to load ownership info from storage. pub fn is_owner(store: &dyn Storage, addr: &Addr) -> StdResult { - let ownership = OWNERSHIP.load(store)?; - - if let Some(owner) = ownership.owner { - if *addr == owner { - return Ok(true); - } - } - - Ok(false) + OWNERSHIP.is_owner(store, addr) } /// Assert that an account is the contract's current owner. pub fn assert_owner(store: &dyn Storage, sender: &Addr) -> 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: &Addr) -> 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(()) + OWNERSHIP.assert_owner(store, sender) } /// Update the contract's ownership info based on the given action. @@ -143,19 +291,12 @@ pub fn update_ownership( sender: &Addr, 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), - } + OWNERSHIP.update_ownership(deps, block, sender, action) } /// Get the current ownership value. pub fn get_ownership(storage: &dyn Storage) -> StdResult> { - OWNERSHIP.load(storage) + OWNERSHIP.get_ownership(storage) } impl Ownership { @@ -202,89 +343,11 @@ impl Ownership { } } -fn none_or(or: Option<&T>) -> String { +// This is a nice helper, maybe move to dedicated utils package? +pub 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: &Addr, - 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(deps.api.addr_validate(new_owner)?), - pending_expiry: expiry, - ..ownership - }) - }) -} - -/// Accept a pending ownership transfer. -fn accept_ownership( - store: &mut dyn Storage, - block: &BlockInfo, - sender: &Addr, -) -> 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: &Addr, -) -> Result, OwnershipError> { - OWNERSHIP.update(store, |ownership| { - check_owner(&ownership, sender)?; - - Ok(Ownership { - owner: None, - pending_owner: None, - pending_expiry: None, - }) - }) -} - //------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------ @@ -296,11 +359,7 @@ mod tests { use super::*; fn mock_addresses() -> [Addr; 3] { - [ - Addr::unchecked("larry"), - Addr::unchecked("jake"), - Addr::unchecked("pumpkin"), - ] + [Addr::unchecked("larry"), Addr::unchecked("jake"), Addr::unchecked("pumpkin")] } fn mock_block_at_height(height: u64) -> BlockInfo { @@ -317,10 +376,10 @@ mod tests { let [larry, _, _] = mock_addresses(); let ownership = - initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); + OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, 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.item.load(deps.as_ref().storage).unwrap()); assert_eq!( ownership, @@ -335,7 +394,7 @@ mod tests { #[test] fn initialize_ownership_no_owner() { let mut deps = mock_dependencies(); - let ownership = initialize_owner(&mut deps.storage, &deps.api, None).unwrap(); + let ownership = OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, None).unwrap(); assert_eq!( ownership, Ownership { @@ -353,20 +412,20 @@ mod tests { // case 1. owner has not renounced { - initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); + OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); - let res = assert_owner(deps.as_ref().storage, &larry); + let res = OWNERSHIP.assert_owner(deps.as_ref().storage, &larry); assert!(res.is_ok()); - let res = assert_owner(deps.as_ref().storage, &jake); + let res = OWNERSHIP.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(); + OWNERSHIP.renounce_ownership(deps.as_mut().storage, &larry).unwrap(); - let res = assert_owner(deps.as_ref().storage, &larry); + let res = OWNERSHIP.assert_owner(deps.as_ref().storage, &larry); assert_eq!(res.unwrap_err(), OwnershipError::NoOwner); } } @@ -376,11 +435,11 @@ mod tests { let mut deps = mock_dependencies(); let [larry, jake, pumpkin] = mock_addresses(); - initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); + OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); // non-owner cannot transfer ownership { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &jake, @@ -395,7 +454,7 @@ mod tests { // owner properly transfers ownership { - let ownership = update_ownership( + let ownership = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &larry, @@ -414,7 +473,7 @@ mod tests { }, ); - let saved_ownership = OWNERSHIP.load(deps.as_ref().storage).unwrap(); + let saved_ownership = OWNERSHIP.item.load(deps.as_ref().storage).unwrap(); assert_eq!(saved_ownership, ownership); } } @@ -424,11 +483,11 @@ mod tests { let mut deps = mock_dependencies(); let [larry, jake, pumpkin] = mock_addresses(); - initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); + OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); // cannot accept ownership when there isn't a pending ownership transfer { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &pumpkin, @@ -438,7 +497,7 @@ mod tests { assert_eq!(err, OwnershipError::TransferNotFound); } - transfer_ownership( + OWNERSHIP.transfer_ownership( deps.as_mut(), &larry, pumpkin.as_str(), @@ -448,7 +507,7 @@ mod tests { // non-pending owner cannot accept ownership { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &jake, @@ -460,7 +519,7 @@ mod tests { // cannot accept ownership if deadline has passed { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(69420), &pumpkin, @@ -472,7 +531,7 @@ mod tests { // pending owner properly accepts ownership before deadline { - let ownership = update_ownership( + let ownership = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(10000), &pumpkin, @@ -488,7 +547,7 @@ mod tests { }, ); - let saved_ownership = OWNERSHIP.load(deps.as_ref().storage).unwrap(); + let saved_ownership = OWNERSHIP.item.load(deps.as_ref().storage).unwrap(); assert_eq!(saved_ownership, ownership); } } @@ -503,11 +562,11 @@ mod tests { pending_owner: Some(pumpkin), pending_expiry: None, }; - OWNERSHIP.save(deps.as_mut().storage, &ownership).unwrap(); + OWNERSHIP.item.save(deps.as_mut().storage, &ownership).unwrap(); // non-owner cannot renounce { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &jake, @@ -519,7 +578,7 @@ mod tests { // owner properly renounces { - let ownership = update_ownership( + let ownership = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &larry, @@ -528,7 +587,7 @@ mod tests { .unwrap(); // ownership returned is same as ownership stored. - assert_eq!(ownership, OWNERSHIP.load(deps.as_ref().storage).unwrap()); + assert_eq!(ownership, OWNERSHIP.item.load(deps.as_ref().storage).unwrap()); assert_eq!( ownership, @@ -542,7 +601,7 @@ mod tests { // cannot renounce twice { - let err = update_ownership( + let err = OWNERSHIP.update_ownership( deps.as_mut(), &mock_block_at_height(12345), &larry, From c8df047c33652e0726786e39357d491e2767e971 Mon Sep 17 00:00:00 2001 From: mr-t Date: Wed, 28 Feb 2024 20:30:22 +0100 Subject: [PATCH 2/4] cargo fmt --- packages/ownable/src/lib.rs | 162 +++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 76 deletions(-) diff --git a/packages/ownable/src/lib.rs b/packages/ownable/src/lib.rs index 3dfb56e..93a6e62 100644 --- a/packages/ownable/src/lib.rs +++ b/packages/ownable/src/lib.rs @@ -439,31 +439,33 @@ mod tests { // non-owner cannot transfer ownership { - let err = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &jake, - Action::TransferOwnership { - new_owner: pumpkin.to_string(), - expiry: None, - }, - ) - .unwrap_err(); + let err = OWNERSHIP + .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 = 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(); + let ownership = 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 { @@ -487,57 +489,62 @@ mod tests { // cannot accept ownership when there isn't a pending ownership transfer { - let err = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &pumpkin, - Action::AcceptOwnership, - ) - .unwrap_err(); + let err = OWNERSHIP + .update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &pumpkin, + Action::AcceptOwnership, + ) + .unwrap_err(); assert_eq!(err, OwnershipError::TransferNotFound); } - OWNERSHIP.transfer_ownership( - deps.as_mut(), - &larry, - pumpkin.as_str(), - Some(Expiration::AtHeight(42069)), - ) - .unwrap(); + OWNERSHIP + .transfer_ownership( + deps.as_mut(), + &larry, + pumpkin.as_str(), + Some(Expiration::AtHeight(42069)), + ) + .unwrap(); // non-pending owner cannot accept ownership { - let err = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &jake, - Action::AcceptOwnership, - ) - .unwrap_err(); + let err = OWNERSHIP + .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 = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(69420), - &pumpkin, - Action::AcceptOwnership, - ) - .unwrap_err(); + let err = OWNERSHIP + .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 = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(10000), - &pumpkin, - Action::AcceptOwnership, - ) - .unwrap(); + let ownership = OWNERSHIP + .update_ownership( + deps.as_mut(), + &mock_block_at_height(10000), + &pumpkin, + Action::AcceptOwnership, + ) + .unwrap(); assert_eq!( ownership, Ownership { @@ -566,25 +573,27 @@ mod tests { // non-owner cannot renounce { - let err = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &jake, - Action::RenounceOwnership, - ) - .unwrap_err(); + let err = OWNERSHIP + .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 = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &larry, - Action::RenounceOwnership, - ) - .unwrap(); + let ownership = 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.item.load(deps.as_ref().storage).unwrap()); @@ -601,13 +610,14 @@ mod tests { // cannot renounce twice { - let err = OWNERSHIP.update_ownership( - deps.as_mut(), - &mock_block_at_height(12345), - &larry, - Action::RenounceOwnership, - ) - .unwrap_err(); + let err = OWNERSHIP + .update_ownership( + deps.as_mut(), + &mock_block_at_height(12345), + &larry, + Action::RenounceOwnership, + ) + .unwrap_err(); assert_eq!(err, OwnershipError::NoOwner); } } From d40ce97bc1cc0e4870591ba8bf4a6160b1ae8b00 Mon Sep 17 00:00:00 2001 From: mr-t Date: Wed, 28 Feb 2024 20:31:38 +0100 Subject: [PATCH 3/4] cargo clippy --tests --- packages/ownable/derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ownable/derive/src/lib.rs b/packages/ownable/derive/src/lib.rs index bf1e82d..8d205ce 100644 --- a/packages/ownable/derive/src/lib.rs +++ b/packages/ownable/derive/src/lib.rs @@ -40,7 +40,7 @@ fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) }; // insert variants from the right to the left - variants.extend(to_add.into_iter()); + variants.extend(to_add); quote! { #left }.into() } From 28c1a09bfc6b4f1942fefe3eb0b50faf9d3b1523 Mon Sep 17 00:00:00 2001 From: mr-t Date: Mon, 18 Mar 2024 12:24:30 +0100 Subject: [PATCH 4/4] use api and storage (instead of DepsMut) for being less restrictive --- packages/ownable/derive/src/lib.rs | 6 ++-- packages/ownable/src/lib.rs | 57 +++++++++++++++++++----------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/packages/ownable/derive/src/lib.rs b/packages/ownable/derive/src/lib.rs index 8d205ce..d962847 100644 --- a/packages/ownable/derive/src/lib.rs +++ b/packages/ownable/derive/src/lib.rs @@ -22,7 +22,8 @@ fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) let Enum(DataEnum { variants, .. - }) = &mut left.data else { + }) = &mut left.data + else { return syn::Error::new(left.ident.span(), "only enums can accept variants") .to_compile_error() .into(); @@ -33,7 +34,8 @@ fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) let Enum(DataEnum { variants: to_add, .. - }) = right.data else { + }) = right.data + else { return syn::Error::new(left.ident.span(), "only enums can provide variants") .to_compile_error() .into(); diff --git a/packages/ownable/src/lib.rs b/packages/ownable/src/lib.rs index 93a6e62..d120109 100644 --- a/packages/ownable/src/lib.rs +++ b/packages/ownable/src/lib.rs @@ -3,7 +3,7 @@ use std::fmt::Display; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Api, Attribute, BlockInfo, DepsMut, StdError, StdResult, Storage}; +use cosmwasm_std::{Addr, Api, Attribute, BlockInfo, StdError, StdResult, Storage}; use cw_address_like::AddressLike; use cw_storage_plus::Item; @@ -102,7 +102,8 @@ impl<'a> OwnershipStore<'a> { /// Return the updated ownership. pub fn update_ownership( &self, - deps: DepsMut, + api: &dyn Api, + storage: &mut dyn Storage, block: &BlockInfo, sender: &Addr, action: Action, @@ -111,9 +112,9 @@ impl<'a> OwnershipStore<'a> { Action::TransferOwnership { new_owner, expiry, - } => self.transfer_ownership(deps, sender, &new_owner, expiry), - Action::AcceptOwnership => self.accept_ownership(deps.storage, block, sender), - Action::RenounceOwnership => self.renounce_ownership(deps.storage, sender), + } => self.transfer_ownership(api, storage, sender, &new_owner, expiry), + Action::AcceptOwnership => self.accept_ownership(storage, block, sender), + Action::RenounceOwnership => self.renounce_ownership(storage, sender), } } @@ -126,12 +127,13 @@ impl<'a> OwnershipStore<'a> { /// optional deadline. fn transfer_ownership( &self, - deps: DepsMut, + api: &dyn Api, + storage: &mut dyn Storage, sender: &Addr, new_owner: &str, expiry: Option, ) -> Result, OwnershipError> { - self.item.update(deps.storage, |ownership| { + self.item.update(storage, |ownership| { // the contract must have an owner self.check_owner(&ownership, sender)?; @@ -147,7 +149,7 @@ impl<'a> OwnershipStore<'a> { // 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(deps.api.addr_validate(new_owner)?), + pending_owner: Some(api.addr_validate(new_owner)?), pending_expiry: expiry, ..ownership }) @@ -286,12 +288,13 @@ pub fn assert_owner(store: &dyn Storage, sender: &Addr) -> Result<(), OwnershipE /// Update the contract's ownership info based on the given action. /// Return the updated ownership. pub fn update_ownership( - deps: DepsMut, + api: &dyn Api, + storage: &mut dyn Storage, block: &BlockInfo, sender: &Addr, action: Action, ) -> Result, OwnershipError> { - OWNERSHIP.update_ownership(deps, block, sender, action) + OWNERSHIP.update_ownership(api, storage, block, sender, action) } /// Get the current ownership value. @@ -441,7 +444,8 @@ mod tests { { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &jake, Action::TransferOwnership { @@ -457,7 +461,8 @@ mod tests { { let ownership = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &larry, Action::TransferOwnership { @@ -485,13 +490,16 @@ mod tests { let mut deps = mock_dependencies(); let [larry, jake, pumpkin] = mock_addresses(); - OWNERSHIP.initialize_owner(&mut deps.storage, &deps.api, Some(larry.as_str())).unwrap(); + OWNERSHIP + .initialize_owner(&mut deps.storage, &deps.api.clone(), Some(larry.as_str())) + .unwrap(); // cannot accept ownership when there isn't a pending ownership transfer { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &pumpkin, Action::AcceptOwnership, @@ -502,7 +510,8 @@ mod tests { OWNERSHIP .transfer_ownership( - deps.as_mut(), + &deps.api.clone().clone(), + deps.as_mut().storage, &larry, pumpkin.as_str(), Some(Expiration::AtHeight(42069)), @@ -513,7 +522,8 @@ mod tests { { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &jake, Action::AcceptOwnership, @@ -526,7 +536,8 @@ mod tests { { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(69420), &pumpkin, Action::AcceptOwnership, @@ -539,7 +550,8 @@ mod tests { { let ownership = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(10000), &pumpkin, Action::AcceptOwnership, @@ -575,7 +587,8 @@ mod tests { { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &jake, Action::RenounceOwnership, @@ -588,7 +601,8 @@ mod tests { { let ownership = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &larry, Action::RenounceOwnership, @@ -612,7 +626,8 @@ mod tests { { let err = OWNERSHIP .update_ownership( - deps.as_mut(), + &deps.api.clone(), + deps.as_mut().storage, &mock_block_at_height(12345), &larry, Action::RenounceOwnership,