From 7e6f5cea76a00214af6f21d694b7218138fe7317 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 22 Jul 2024 03:54:17 -0400 Subject: [PATCH] started adding pre-propose migration to v2.5.0 (#854) --- Cargo.lock | 239 ++++++++++++------ Cargo.toml | 9 + .../examples/schema.rs | 3 +- .../dao-pre-propose-approval-single.json | 134 +++++++++- .../src/contract.rs | 11 +- .../src/msg.rs | 4 +- .../examples/schema.rs | 3 +- .../schema/dao-pre-propose-approver.json | 134 +++++++++- .../dao-pre-propose-approver/src/contract.rs | 11 +- .../dao-pre-propose-approver/src/msg.rs | 4 +- .../examples/schema.rs | 11 +- .../schema/dao-pre-propose-multiple.json | 134 +++++++++- .../dao-pre-propose-multiple/src/contract.rs | 13 +- .../dao-pre-propose-multiple/src/lib.rs | 2 +- .../dao-pre-propose-single/examples/schema.rs | 11 +- .../schema/dao-pre-propose-single.json | 134 +++++++++- .../dao-pre-propose-single/src/contract.rs | 13 +- .../dao-pre-propose-single/src/lib.rs | 2 +- packages/dao-pre-propose-base/Cargo.toml | 6 + packages/dao-pre-propose-base/src/error.rs | 3 + packages/dao-pre-propose-base/src/execute.rs | 98 ++++++- packages/dao-pre-propose-base/src/msg.rs | 15 ++ packages/dao-pre-propose-base/src/state.rs | 12 +- packages/dao-pre-propose-base/src/tests.rs | 2 +- 24 files changed, 888 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0dedb404..6abb0e65f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,7 +273,7 @@ dependencies = [ "cw20 1.1.2", "cw20-stake 2.5.0", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-pre-propose-single", "dao-proposal-single", "dao-voting 2.5.0", @@ -305,7 +305,7 @@ dependencies = [ "cw-utils 1.0.3", "cw2 1.1.2", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 2.5.0", @@ -701,7 +701,7 @@ dependencies = [ "cw20-base 1.1.2", "cw4 1.1.2", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 2.5.0", @@ -820,6 +820,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cw-denom" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "decaa8be7ffa8090dc62d8bb8ee97cd3f41f815a41ba08de1d40cacef6c3cb4b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw20 1.1.2", + "thiserror", +] + [[package]] name = "cw-denom" version = "2.5.0" @@ -847,11 +859,23 @@ dependencies = [ "cw20-base 1.1.2", "cw20-stake 2.5.0", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-voting-cw20-staked", "thiserror", ] +[[package]] +name = "cw-hooks" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f101e1019c31f5e7ed444fc4de29c004a5e724dd0f953d7cf1ee4f1a5a56e6" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "thiserror", +] + [[package]] name = "cw-hooks" version = "2.5.0" @@ -936,7 +960,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-multi-test", "cw-ownable", "cw-storage-plus 1.2.0", @@ -1053,7 +1077,7 @@ dependencies = [ "cw-storage-plus 1.2.0", "cw-tokenfactory-types", "cw2 1.1.2", - "dao-interface", + "dao-interface 2.5.0", "osmosis-std", "osmosis-test-tube", "prost 0.12.3", @@ -1069,7 +1093,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "dao-interface", + "dao-interface 2.5.0", "osmosis-std", "osmosis-std-derive", "prost 0.12.3", @@ -1140,7 +1164,7 @@ dependencies = [ "anyhow", "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-multi-test", "cw-ownable", "cw-stake-tracker", @@ -1331,7 +1355,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers 1.1.2", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-ownable", "cw-paginate-storage 2.5.0", @@ -1632,21 +1656,33 @@ dependencies = [ "cw20-base 1.1.2", "cw721 0.18.0", "cw721-base 0.18.0", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "dao-proposal-sudo", "dao-voting-cw20-balance", "thiserror", ] +[[package]] +name = "dao-dao-macros" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5051616aa30863bb919b01113fc93f578ce1da45e9162bcfccdfb96d5832bc20" +dependencies = [ + "cosmwasm-schema", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "dao-dao-macros" version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-hooks", - "dao-interface", + "cw-hooks 2.5.0", + "dao-interface 2.5.0", "dao-voting 2.5.0", "proc-macro2", "quote", @@ -1659,12 +1695,27 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-hooks", + "cw-hooks 2.5.0", "cw4 1.1.2", - "dao-pre-propose-base", + "dao-pre-propose-base 2.5.0", "dao-voting 2.5.0", ] +[[package]] +name = "dao-interface" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4895da96b53c77592f6728fd21dfed4b9aff653fac8d1ee5dceb96353c7045" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw721 0.18.0", + "osmosis-std", +] + [[package]] name = "dao-interface" version = "2.5.0" @@ -1702,7 +1753,7 @@ dependencies = [ "cw4 0.13.4", "cw4-voting", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 0.1.0", @@ -1718,7 +1769,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-multi-test", "cw-paginate-storage 2.5.0", "cw-storage-plus 1.2.0", @@ -1729,8 +1780,8 @@ dependencies = [ "cw4-group 1.1.2", "dao-dao-core", "dao-hooks", - "dao-interface", - "dao-pre-propose-base", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 2.5.0", @@ -1745,7 +1796,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -1755,9 +1806,9 @@ dependencies = [ "cw4-group 1.1.2", "dao-dao-core", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-pre-propose-approval-single", - "dao-pre-propose-base", + "dao-pre-propose-base 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 2.5.0", @@ -1765,20 +1816,43 @@ dependencies = [ "dao-voting-cw4", ] +[[package]] +name = "dao-pre-propose-base" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd285523d7dea35a0dd76f0a5f20c190935922a7b58fe0ec753eb407e68d718b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.4.1", + "cw-hooks 2.4.1", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "dao-interface 2.4.1", + "dao-voting 2.4.1", + "serde", + "thiserror", +] + [[package]] name = "dao-pre-propose-base" version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", - "cw-hooks", + "cw-denom 2.4.1", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", - "dao-interface", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", "dao-voting 2.5.0", + "semver", "serde", "thiserror", ] @@ -1789,7 +1863,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-multi-test", "cw-utils 1.0.3", "cw2 1.1.2", @@ -1798,8 +1872,8 @@ dependencies = [ "cw4-group 1.1.2", "dao-dao-core", "dao-hooks", - "dao-interface", - "dao-pre-propose-base", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", "dao-proposal-multiple", "dao-testing", "dao-voting 2.5.0", @@ -1813,8 +1887,8 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", - "cw-hooks", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", "cw-multi-test", "cw-utils 1.0.3", "cw2 1.1.2", @@ -1823,8 +1897,8 @@ dependencies = [ "cw4-group 1.1.2", "dao-dao-core", "dao-hooks", - "dao-interface", - "dao-pre-propose-base", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", "dao-proposal-single", "dao-testing", "dao-voting 2.5.0", @@ -1846,8 +1920,8 @@ dependencies = [ "cw4 1.1.2", "cw4-group 1.1.2", "dao-dao-core", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "dao-testing", "dao-voting 2.5.0", "dao-voting-cw4", @@ -1860,7 +1934,7 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -1869,7 +1943,7 @@ dependencies = [ "cw20-base 1.1.2", "dao-dao-core", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-single", "dao-voting 2.5.0", "dao-voting-cw20-balance", @@ -1883,8 +1957,8 @@ dependencies = [ "anyhow", "cosmwasm-schema", "cosmwasm-std", - "cw-denom", - "cw-hooks", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -1895,10 +1969,10 @@ dependencies = [ "cw4 1.1.2", "cw4-group 1.1.2", "cw721-base 0.18.0", - "dao-dao-macros", + "dao-dao-macros 2.5.0", "dao-hooks", - "dao-interface", - "dao-pre-propose-base", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", "dao-pre-propose-multiple", "dao-testing", "dao-voting 0.1.0", @@ -1920,8 +1994,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-core", - "cw-denom", - "cw-hooks", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", "cw-multi-test", "cw-proposal-single", "cw-storage-plus 1.2.0", @@ -1935,10 +2009,10 @@ dependencies = [ "cw4-group 1.1.2", "cw721-base 0.18.0", "dao-dao-core", - "dao-dao-macros", + "dao-dao-macros 2.5.0", "dao-hooks", - "dao-interface", - "dao-pre-propose-base", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", "dao-pre-propose-single", "dao-testing", "dao-voting 0.1.0", @@ -1960,8 +2034,8 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw2 1.1.2", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "thiserror", ] @@ -1985,7 +2059,7 @@ dependencies = [ "cw4-group 1.1.2", "cw721-base 0.18.0", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-testing", "dao-voting 2.5.0", "dao-voting-cw20-staked", @@ -2009,8 +2083,8 @@ dependencies = [ "cw2 1.1.2", "cw721 0.18.0", "cw721-base 0.18.0", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "dao-voting 2.5.0", "thiserror", ] @@ -2023,7 +2097,7 @@ dependencies = [ "cosmwasm-std", "cw-admin-factory", "cw-core", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-proposal-single", "cw-tokenfactory-issuer", @@ -2038,7 +2112,7 @@ dependencies = [ "cw721-base 0.18.0", "cw721-roles", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-pre-propose-multiple", "dao-pre-propose-single", "dao-proposal-condorcet", @@ -2073,18 +2147,35 @@ dependencies = [ "thiserror", ] +[[package]] +name = "dao-voting" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945898e8e168eada7ed06fa713d679e541673ee0dd8c70aee8d1f224ccd031a0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.4.1", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20 1.1.2", + "dao-dao-macros 2.4.1", + "dao-interface 2.4.1", + "thiserror", +] + [[package]] name = "dao-voting" version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-denom", + "cw-denom 2.5.0", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw20 1.1.2", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "thiserror", ] @@ -2100,8 +2191,8 @@ dependencies = [ "cw2 1.1.2", "cw20 1.1.2", "cw20-base 1.1.2", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "thiserror", ] @@ -2118,8 +2209,8 @@ dependencies = [ "cw20 1.1.2", "cw20-base 1.1.2", "cw20-stake 2.5.0", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "dao-voting 2.5.0", "thiserror", ] @@ -2136,8 +2227,8 @@ dependencies = [ "cw2 1.1.2", "cw4 1.1.2", "cw4-group 1.1.2", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "thiserror", ] @@ -2159,8 +2250,8 @@ dependencies = [ "cw721-controllers", "cw721-roles", "dao-cw721-extensions", - "dao-dao-macros", - "dao-interface", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", "dao-testing", "thiserror", ] @@ -2173,7 +2264,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers 1.1.2", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -2181,9 +2272,9 @@ dependencies = [ "cw721 0.18.0", "cw721-base 0.18.0", "cw721-controllers", - "dao-dao-macros", + "dao-dao-macros 2.5.0", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-hook-counter", "dao-proposal-single", "dao-test-custom-factory", @@ -2203,15 +2294,15 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers 1.1.2", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", "cw721-controllers", - "dao-dao-macros", + "dao-dao-macros 2.5.0", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-hook-counter", "dao-proposal-single", "dao-test-custom-factory", @@ -2232,16 +2323,16 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers 1.1.2", - "cw-hooks", + "cw-hooks 2.5.0", "cw-multi-test", "cw-ownable", "cw-storage-plus 1.2.0", "cw-tokenfactory-issuer", "cw-utils 1.0.3", "cw2 1.1.2", - "dao-dao-macros", + "dao-dao-macros 2.5.0", "dao-hooks", - "dao-interface", + "dao-interface 2.5.0", "dao-proposal-hook-counter", "dao-proposal-single", "dao-test-custom-factory", @@ -2939,7 +3030,7 @@ dependencies = [ "cw721-base 0.18.0", "cw721-roles", "dao-dao-core", - "dao-interface", + "dao-interface 2.5.0", "dao-pre-propose-single", "dao-proposal-single", "dao-test-custom-factory", diff --git a/Cargo.toml b/Cargo.toml index c9a716f76..135bbf99c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ prost-types = { version = "0.12.3", default-features = false } quote = "1.0" rand = "0.8" schemars = "0.8" +semver = "1.0.20" serde = { version = "1.0", default-features = false, features = ["derive"] } serde-cw-value = "0.7" serde_json = "1.0" @@ -135,3 +136,11 @@ cw20-staked-balance-voting-v1 = { package = "cw20-staked-balance-voting", versio cw4-voting-v1 = { package = "cw4-voting", version = "0.1.0" } stake-cw20-v03 = { package = "stake-cw20", version = "0.2.6" } voting-v1 = { package = "dao-voting", version = "0.1.0" } + +# v2.4.1 dependencies. used for state migrations. +cw-denom-v241 = { package = "cw-denom", version = "2.4.1" } +dao-dao-core-v241 = { package = "dao-dao-core", version = "2.4.1" } +dao-pre-propose-base-v241 = { package = "dao-pre-propose-base", version = "2.4.1" } +dao-pre-propose-single-v241 = { package = "dao-pre-propose-single", version = "2.4.1" } +dao-voting-cw4-v241 = { package = "dao-voting-cw4", version = "2.4.1" } +dao-voting-v241 = { package = "dao-voting", version = "2.4.1" } diff --git a/contracts/pre-propose/dao-pre-propose-approval-single/examples/schema.rs b/contracts/pre-propose/dao-pre-propose-approval-single/examples/schema.rs index 514f8152e..122a90a08 100644 --- a/contracts/pre-propose/dao-pre-propose-approval-single/examples/schema.rs +++ b/contracts/pre-propose/dao-pre-propose-approval-single/examples/schema.rs @@ -1,10 +1,11 @@ use cosmwasm_schema::write_api; -use dao_pre_propose_approval_single::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use dao_pre_propose_approval_single::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { instantiate: InstantiateMsg, query: QueryMsg, execute: ExecuteMsg, + migrate: MigrateMsg, } } diff --git a/contracts/pre-propose/dao-pre-propose-approval-single/schema/dao-pre-propose-approval-single.json b/contracts/pre-propose/dao-pre-propose-approval-single/schema/dao-pre-propose-approval-single.json index bc211ecd8..060a12f52 100644 --- a/contracts/pre-propose/dao-pre-propose-approval-single/schema/dao-pre-propose-approval-single.json +++ b/contracts/pre-propose/dao-pre-propose-approval-single/schema/dao-pre-propose-approval-single.json @@ -2275,7 +2275,139 @@ } } }, - "migrate": null, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_under_v250" + ], + "properties": { + "from_under_v250": { + "type": "object", + "properties": { + "policy": { + "description": "Optionally set a new submission policy with more granular controls. If not set, the current policy will remain.", + "anyOf": [ + { + "$ref": "#/definitions/PreProposeSubmissionPolicy" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "extension" + ], + "properties": { + "extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "PreProposeSubmissionPolicy": { + "description": "The policy configured in a pre-propose module that determines who can submit proposals. This is the preferred way to restrict proposal creation (as opposed to the ProposalCreationPolicy above) since pre-propose modules support other features, such as proposal deposits.", + "oneOf": [ + { + "description": "Anyone may create proposals, except for those in the denylist.", + "type": "object", + "required": [ + "anyone" + ], + "properties": { + "anyone": { + "type": "object", + "properties": { + "denylist": { + "description": "Addresses that may not create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Specific people may create proposals.", + "type": "object", + "required": [ + "specific" + ], + "properties": { + "specific": { + "type": "object", + "required": [ + "dao_members" + ], + "properties": { + "allowlist": { + "description": "Addresses that may create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "dao_members": { + "description": "Whether or not DAO members may create proposals.", + "type": "boolean" + }, + "denylist": { + "description": "Addresses that may not create proposals, overriding other settings.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, "sudo": null, "responses": { "can_propose": { diff --git a/contracts/pre-propose/dao-pre-propose-approval-single/src/contract.rs b/contracts/pre-propose/dao-pre-propose-approval-single/src/contract.rs index 06714deee..b062fdcf6 100644 --- a/contracts/pre-propose/dao-pre-propose-approval-single/src/contract.rs +++ b/contracts/pre-propose/dao-pre-propose-approval-single/src/contract.rs @@ -13,8 +13,8 @@ use dao_voting::deposit::DepositRefundPolicy; use dao_voting::proposal::SingleChoiceProposeMsg as ProposeMsg; use crate::msg::{ - ApproverProposeMessage, ExecuteExt, ExecuteMsg, InstantiateExt, InstantiateMsg, ProposeMessage, - ProposeMessageInternal, QueryExt, QueryMsg, + ApproverProposeMessage, ExecuteExt, ExecuteMsg, InstantiateExt, InstantiateMsg, MigrateMsg, + ProposeMessage, ProposeMessageInternal, QueryExt, QueryMsg, }; use crate::state::{ advance_approval_id, Proposal, ProposalStatus, APPROVER, COMPLETED_PROPOSALS, @@ -24,7 +24,7 @@ use crate::state::{ pub(crate) const CONTRACT_NAME: &str = "crates.io:dao-pre-propose-approval-single"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -type PrePropose = PreProposeContract; +type PrePropose = PreProposeContract; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -403,3 +403,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { _ => PrePropose::default().query(deps, env, msg), } } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + PrePropose::default().migrate(deps, msg) +} diff --git a/contracts/pre-propose/dao-pre-propose-approval-single/src/msg.rs b/contracts/pre-propose/dao-pre-propose-approval-single/src/msg.rs index 25bc7ea84..381606d1d 100644 --- a/contracts/pre-propose/dao-pre-propose-approval-single/src/msg.rs +++ b/contracts/pre-propose/dao-pre-propose-approval-single/src/msg.rs @@ -1,7 +1,8 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; use dao_pre_propose_base::msg::{ - ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, QueryMsg as QueryBase, + ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, MigrateMsg as MigrateBase, + QueryMsg as QueryBase, }; use dao_voting::{proposal::SingleChoiceProposeMsg as ProposeMsg, voting::SingleChoiceAutoVote}; @@ -87,6 +88,7 @@ pub enum QueryExt { pub type InstantiateMsg = InstantiateBase; pub type ExecuteMsg = ExecuteBase; pub type QueryMsg = QueryBase; +pub type MigrateMsg = MigrateBase; /// Internal version of the propose message that includes the /// `proposer` field. The module will fill this in based on the sender diff --git a/contracts/pre-propose/dao-pre-propose-approver/examples/schema.rs b/contracts/pre-propose/dao-pre-propose-approver/examples/schema.rs index 51cb0cbf3..fd26dfa01 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/examples/schema.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/examples/schema.rs @@ -1,10 +1,11 @@ use cosmwasm_schema::write_api; -use dao_pre_propose_approver::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use dao_pre_propose_approver::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { instantiate: InstantiateMsg, query: QueryMsg, execute: ExecuteMsg, + migrate: MigrateMsg, } } diff --git a/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json b/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json index 477b52d77..82f095399 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json +++ b/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json @@ -889,7 +889,139 @@ } } }, - "migrate": null, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_under_v250" + ], + "properties": { + "from_under_v250": { + "type": "object", + "properties": { + "policy": { + "description": "Optionally set a new submission policy with more granular controls. If not set, the current policy will remain.", + "anyOf": [ + { + "$ref": "#/definitions/PreProposeSubmissionPolicy" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "extension" + ], + "properties": { + "extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "PreProposeSubmissionPolicy": { + "description": "The policy configured in a pre-propose module that determines who can submit proposals. This is the preferred way to restrict proposal creation (as opposed to the ProposalCreationPolicy above) since pre-propose modules support other features, such as proposal deposits.", + "oneOf": [ + { + "description": "Anyone may create proposals, except for those in the denylist.", + "type": "object", + "required": [ + "anyone" + ], + "properties": { + "anyone": { + "type": "object", + "properties": { + "denylist": { + "description": "Addresses that may not create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Specific people may create proposals.", + "type": "object", + "required": [ + "specific" + ], + "properties": { + "specific": { + "type": "object", + "required": [ + "dao_members" + ], + "properties": { + "allowlist": { + "description": "Addresses that may create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "dao_members": { + "description": "Whether or not DAO members may create proposals.", + "type": "boolean" + }, + "denylist": { + "description": "Addresses that may not create proposals, overriding other settings.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, "sudo": null, "responses": { "can_propose": { diff --git a/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs b/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs index 9dcb23c93..cd45c6703 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs @@ -15,8 +15,8 @@ use dao_voting::pre_propose::PreProposeSubmissionPolicy; use dao_voting::status::Status; use crate::msg::{ - BaseInstantiateMsg, ExecuteExt, ExecuteMsg, InstantiateMsg, ProposeMessageInternal, QueryExt, - QueryMsg, + BaseInstantiateMsg, ExecuteExt, ExecuteMsg, InstantiateMsg, MigrateMsg, ProposeMessageInternal, + QueryExt, QueryMsg, }; use crate::state::{ PRE_PROPOSE_APPROVAL_CONTRACT, PRE_PROPOSE_ID_TO_PROPOSAL_ID, PROPOSAL_ID_TO_PRE_PROPOSE_ID, @@ -25,7 +25,7 @@ use crate::state::{ pub(crate) const CONTRACT_NAME: &str = "crates.io:dao-pre-propose-approver"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -type PrePropose = PreProposeContract; +type PrePropose = PreProposeContract; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -256,3 +256,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { _ => PrePropose::default().query(deps, env, msg), } } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + PrePropose::default().migrate(deps, msg) +} diff --git a/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs b/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs index 7d4529856..5482fad8c 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs @@ -2,7 +2,8 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; use dao_pre_propose_approval_single::msg::ApproverProposeMessage; use dao_pre_propose_base::msg::{ - ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, QueryMsg as QueryBase, + ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, MigrateMsg as MigrateBase, + QueryMsg as QueryBase, }; #[cw_serde] @@ -31,6 +32,7 @@ pub enum QueryExt { pub type BaseInstantiateMsg = InstantiateBase; pub type ExecuteMsg = ExecuteBase; pub type QueryMsg = QueryBase; +pub type MigrateMsg = MigrateBase; /// Internal version of the propose message that includes the /// `proposer` field. The module will fill this in based on the sender diff --git a/contracts/pre-propose/dao-pre-propose-multiple/examples/schema.rs b/contracts/pre-propose/dao-pre-propose-multiple/examples/schema.rs index e75470342..e03b233b7 100644 --- a/contracts/pre-propose/dao-pre-propose-multiple/examples/schema.rs +++ b/contracts/pre-propose/dao-pre-propose-multiple/examples/schema.rs @@ -1,12 +1,11 @@ use cosmwasm_schema::write_api; -use cosmwasm_std::Empty; -use dao_pre_propose_base::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use dao_pre_propose_multiple::ProposeMessage; +use dao_pre_propose_multiple::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { - instantiate: InstantiateMsg, - query: QueryMsg, - execute: ExecuteMsg, + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg } } diff --git a/contracts/pre-propose/dao-pre-propose-multiple/schema/dao-pre-propose-multiple.json b/contracts/pre-propose/dao-pre-propose-multiple/schema/dao-pre-propose-multiple.json index b4f9a74c2..a39977ce6 100644 --- a/contracts/pre-propose/dao-pre-propose-multiple/schema/dao-pre-propose-multiple.json +++ b/contracts/pre-propose/dao-pre-propose-multiple/schema/dao-pre-propose-multiple.json @@ -1960,7 +1960,139 @@ } } }, - "migrate": null, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_under_v250" + ], + "properties": { + "from_under_v250": { + "type": "object", + "properties": { + "policy": { + "description": "Optionally set a new submission policy with more granular controls. If not set, the current policy will remain.", + "anyOf": [ + { + "$ref": "#/definitions/PreProposeSubmissionPolicy" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "extension" + ], + "properties": { + "extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "PreProposeSubmissionPolicy": { + "description": "The policy configured in a pre-propose module that determines who can submit proposals. This is the preferred way to restrict proposal creation (as opposed to the ProposalCreationPolicy above) since pre-propose modules support other features, such as proposal deposits.", + "oneOf": [ + { + "description": "Anyone may create proposals, except for those in the denylist.", + "type": "object", + "required": [ + "anyone" + ], + "properties": { + "anyone": { + "type": "object", + "properties": { + "denylist": { + "description": "Addresses that may not create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Specific people may create proposals.", + "type": "object", + "required": [ + "specific" + ], + "properties": { + "specific": { + "type": "object", + "required": [ + "dao_members" + ], + "properties": { + "allowlist": { + "description": "Addresses that may create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "dao_members": { + "description": "Whether or not DAO members may create proposals.", + "type": "boolean" + }, + "denylist": { + "description": "Addresses that may not create proposals, overriding other settings.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, "sudo": null, "responses": { "can_propose": { diff --git a/contracts/pre-propose/dao-pre-propose-multiple/src/contract.rs b/contracts/pre-propose/dao-pre-propose-multiple/src/contract.rs index 4c1d03126..a93957a22 100644 --- a/contracts/pre-propose/dao-pre-propose-multiple/src/contract.rs +++ b/contracts/pre-propose/dao-pre-propose-multiple/src/contract.rs @@ -6,7 +6,10 @@ use cw2::set_contract_version; use dao_pre_propose_base::{ error::PreProposeError, - msg::{ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, QueryMsg as QueryBase}, + msg::{ + ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, MigrateMsg as MigrateBase, + QueryMsg as QueryBase, + }, state::PreProposeContract, }; use dao_voting::{ @@ -30,6 +33,7 @@ pub enum ProposeMessage { pub type InstantiateMsg = InstantiateBase; pub type ExecuteMsg = ExecuteBase; pub type QueryMsg = QueryBase; +pub type MigrateMsg = MigrateBase; /// Internal version of the propose message that includes the /// `proposer` field. The module will fill this in based on the sender @@ -39,7 +43,7 @@ enum ProposeMessageInternal { Propose(ProposeMsg), } -type PrePropose = PreProposeContract; +type PrePropose = PreProposeContract; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -127,3 +131,8 @@ pub fn execute( pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { PrePropose::default().query(deps, env, msg) } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + PrePropose::default().migrate(deps, msg) +} diff --git a/contracts/pre-propose/dao-pre-propose-multiple/src/lib.rs b/contracts/pre-propose/dao-pre-propose-multiple/src/lib.rs index 16d6ba5ae..33df46b46 100644 --- a/contracts/pre-propose/dao-pre-propose-multiple/src/lib.rs +++ b/contracts/pre-propose/dao-pre-propose-multiple/src/lib.rs @@ -5,7 +5,7 @@ pub mod contract; #[cfg(test)] mod tests; -pub use contract::{ExecuteMsg, InstantiateMsg, ProposeMessage, QueryMsg}; +pub use contract::{ExecuteMsg, InstantiateMsg, MigrateMsg, ProposeMessage, QueryMsg}; // Exporting these means that contracts interacting with this one don't // need an explicit dependency on the base contract to read queries. diff --git a/contracts/pre-propose/dao-pre-propose-single/examples/schema.rs b/contracts/pre-propose/dao-pre-propose-single/examples/schema.rs index 8841e17bd..908c4c2d5 100644 --- a/contracts/pre-propose/dao-pre-propose-single/examples/schema.rs +++ b/contracts/pre-propose/dao-pre-propose-single/examples/schema.rs @@ -1,12 +1,11 @@ use cosmwasm_schema::write_api; -use cosmwasm_std::Empty; -use dao_pre_propose_base::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use dao_pre_propose_single::ProposeMessage; +use dao_pre_propose_single::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; fn main() { write_api! { - instantiate: InstantiateMsg, - query: QueryMsg, - execute: ExecuteMsg, + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg } } diff --git a/contracts/pre-propose/dao-pre-propose-single/schema/dao-pre-propose-single.json b/contracts/pre-propose/dao-pre-propose-single/schema/dao-pre-propose-single.json index f96180633..83c0fac71 100644 --- a/contracts/pre-propose/dao-pre-propose-single/schema/dao-pre-propose-single.json +++ b/contracts/pre-propose/dao-pre-propose-single/schema/dao-pre-propose-single.json @@ -1934,7 +1934,139 @@ } } }, - "migrate": null, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_under_v250" + ], + "properties": { + "from_under_v250": { + "type": "object", + "properties": { + "policy": { + "description": "Optionally set a new submission policy with more granular controls. If not set, the current policy will remain.", + "anyOf": [ + { + "$ref": "#/definitions/PreProposeSubmissionPolicy" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "extension" + ], + "properties": { + "extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "PreProposeSubmissionPolicy": { + "description": "The policy configured in a pre-propose module that determines who can submit proposals. This is the preferred way to restrict proposal creation (as opposed to the ProposalCreationPolicy above) since pre-propose modules support other features, such as proposal deposits.", + "oneOf": [ + { + "description": "Anyone may create proposals, except for those in the denylist.", + "type": "object", + "required": [ + "anyone" + ], + "properties": { + "anyone": { + "type": "object", + "properties": { + "denylist": { + "description": "Addresses that may not create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Specific people may create proposals.", + "type": "object", + "required": [ + "specific" + ], + "properties": { + "specific": { + "type": "object", + "required": [ + "dao_members" + ], + "properties": { + "allowlist": { + "description": "Addresses that may create proposals.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "dao_members": { + "description": "Whether or not DAO members may create proposals.", + "type": "boolean" + }, + "denylist": { + "description": "Addresses that may not create proposals, overriding other settings.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, "sudo": null, "responses": { "can_propose": { diff --git a/contracts/pre-propose/dao-pre-propose-single/src/contract.rs b/contracts/pre-propose/dao-pre-propose-single/src/contract.rs index 9f65d7f06..d159d823f 100644 --- a/contracts/pre-propose/dao-pre-propose-single/src/contract.rs +++ b/contracts/pre-propose/dao-pre-propose-single/src/contract.rs @@ -8,7 +8,10 @@ use cw2::set_contract_version; use dao_pre_propose_base::{ error::PreProposeError, - msg::{ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, QueryMsg as QueryBase}, + msg::{ + ExecuteMsg as ExecuteBase, InstantiateMsg as InstantiateBase, MigrateMsg as MigrateBase, + QueryMsg as QueryBase, + }, state::PreProposeContract, }; use dao_voting::{proposal::SingleChoiceProposeMsg as ProposeMsg, voting::SingleChoiceAutoVote}; @@ -33,6 +36,7 @@ pub enum ProposeMessage { pub type InstantiateMsg = InstantiateBase; pub type ExecuteMsg = ExecuteBase; pub type QueryMsg = QueryBase; +pub type MigrateMsg = MigrateBase; /// Internal version of the propose message that includes the /// `proposer` field. The module will fill this in based on the sender @@ -42,7 +46,7 @@ enum ProposeMessageInternal { Propose(ProposeMsg), } -type PrePropose = PreProposeContract; +type PrePropose = PreProposeContract; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -131,3 +135,8 @@ pub fn execute( pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { PrePropose::default().query(deps, env, msg) } + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + PrePropose::default().migrate(deps, msg) +} diff --git a/contracts/pre-propose/dao-pre-propose-single/src/lib.rs b/contracts/pre-propose/dao-pre-propose-single/src/lib.rs index 16d6ba5ae..33df46b46 100644 --- a/contracts/pre-propose/dao-pre-propose-single/src/lib.rs +++ b/contracts/pre-propose/dao-pre-propose-single/src/lib.rs @@ -5,7 +5,7 @@ pub mod contract; #[cfg(test)] mod tests; -pub use contract::{ExecuteMsg, InstantiateMsg, ProposeMessage, QueryMsg}; +pub use contract::{ExecuteMsg, InstantiateMsg, MigrateMsg, ProposeMessage, QueryMsg}; // Exporting these means that contracts interacting with this one don't // need an explicit dependency on the base contract to read queries. diff --git a/packages/dao-pre-propose-base/Cargo.toml b/packages/dao-pre-propose-base/Cargo.toml index c063d34f9..012273f2a 100644 --- a/packages/dao-pre-propose-base/Cargo.toml +++ b/packages/dao-pre-propose-base/Cargo.toml @@ -28,6 +28,12 @@ dao-interface = { workspace = true } dao-voting = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } +semver = { workspace = true } + +# v2.4.0 packages for state migration +cw-denom-v241 = { workspace = true } +dao-pre-propose-base-v241 = { workspace = true } +dao-voting-v241 = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/packages/dao-pre-propose-base/src/error.rs b/packages/dao-pre-propose-base/src/error.rs index 762ffa768..fc3bbaefb 100644 --- a/packages/dao-pre-propose-base/src/error.rs +++ b/packages/dao-pre-propose-base/src/error.rs @@ -54,4 +54,7 @@ pub enum PreProposeError { #[error("Unsupported")] Unsupported {}, + + #[error("Cannot migrate contract version {actual}. Requires: {required}")] + CannotMigrateVersion { required: String, actual: String }, } diff --git a/packages/dao-pre-propose-base/src/execute.rs b/packages/dao-pre-propose-base/src/execute.rs index 21bcee3a5..5e47b154a 100644 --- a/packages/dao-pre-propose-base/src/execute.rs +++ b/packages/dao-pre-propose-base/src/execute.rs @@ -1,15 +1,17 @@ use cosmwasm_schema::schemars::JsonSchema; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, - SubMsg, WasmMsg, + to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdError, + StdResult, SubMsg, WasmMsg, }; -use cw2::set_contract_version; +use semver::{Version, VersionReq}; -use cw_denom::UncheckedDenom; +use cw2::{get_contract_version, set_contract_version, ContractVersion}; + +use cw_denom::{CheckedDenom, UncheckedDenom}; use dao_interface::voting::{Query as CwCoreQuery, VotingPowerAtHeightResponse}; use dao_voting::{ - deposit::{DepositRefundPolicy, UncheckedDepositInfo}, + deposit::{CheckedDepositInfo, DepositRefundPolicy, UncheckedDepositInfo}, pre_propose::{PreProposeSubmissionPolicy, PreProposeSubmissionPolicyError}, status::Status, }; @@ -17,18 +19,23 @@ use serde::Serialize; use crate::{ error::PreProposeError, - msg::{DepositInfoResponse, ExecuteMsg, InstantiateMsg, QueryMsg}, + msg::{DepositInfoResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, state::{Config, PreProposeContract}, }; +use cw_denom_v241::CheckedDenom as CheckedDenomV241; +use dao_pre_propose_base_v241::state::PreProposeContract as PreProposeContractV241; +use dao_voting_v241::deposit::DepositRefundPolicy as DepositRefundPolicyV241; + const CONTRACT_NAME: &str = "crates.io::dao-pre-propose-base"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -impl - PreProposeContract +impl + PreProposeContract where ProposalMessage: Serialize, QueryExt: JsonSchema, + MigrateExt: JsonSchema, { pub fn instantiate( &self, @@ -600,4 +607,79 @@ where QueryMsg::QueryExtension { .. } => Ok(Binary::default()), } } + + pub fn migrate( + &self, + deps: DepsMut, + msg: MigrateMsg, + ) -> Result { + match msg { + MigrateMsg::FromUnderV250 { policy } => { + // all contracts >= v2.0.0 and < v2.5.0 have the same config + let required_str = ">=2.0.0, <2.5.0"; + // ensure acceptable version + let requirement = VersionReq::parse(required_str).unwrap(); + let ContractVersion { version, .. } = get_contract_version(deps.storage)?; + let sem_version = Version::parse(&version).unwrap(); + + if !requirement.matches(&sem_version) { + return Err(PreProposeError::CannotMigrateVersion { + required: required_str.to_string(), + actual: version.clone(), + }); + } + + let old_contract = PreProposeContractV241::::default(); + let old_config = old_contract.config.load(deps.storage)?; + + // if provided a policy to update with, use it + let submission_policy = if let Some(submission_policy) = policy { + submission_policy + + // otherwise convert old `open_proposal_submission` flag + // into new policy enum + } else if old_config.open_proposal_submission { + PreProposeSubmissionPolicy::Anyone { denylist: None } + } else { + PreProposeSubmissionPolicy::Specific { + dao_members: true, + allowlist: None, + denylist: None, + } + }; + + let deposit_info: Option = + old_config.deposit_info.map(|old| CheckedDepositInfo { + denom: match old.denom { + CheckedDenomV241::Cw20(address) => CheckedDenom::Cw20(address), + CheckedDenomV241::Native(denom) => CheckedDenom::Native(denom), + }, + amount: old.amount, + refund_policy: match old.refund_policy { + DepositRefundPolicyV241::Always => DepositRefundPolicy::Always, + DepositRefundPolicyV241::Never => DepositRefundPolicy::Never, + DepositRefundPolicyV241::OnlyPassed => DepositRefundPolicy::OnlyPassed, + }, + }); + + self.config.save( + deps.storage, + &Config { + deposit_info, + submission_policy, + }, + )?; + + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Response::default() + .add_attribute("action", "migrate") + .add_attribute("from", version) + .add_attribute("to", CONTRACT_VERSION)) + } + MigrateMsg::Extension { .. } => Err(PreProposeError::Std(StdError::generic_err( + "not implemented", + ))), + } + } } diff --git a/packages/dao-pre-propose-base/src/msg.rs b/packages/dao-pre-propose-base/src/msg.rs index e795969e9..45dfe412d 100644 --- a/packages/dao-pre-propose-base/src/msg.rs +++ b/packages/dao-pre-propose-base/src/msg.rs @@ -148,3 +148,18 @@ pub struct DepositInfoResponse { /// The address that created the proposal. pub proposer: cosmwasm_std::Addr, } + +#[cw_serde] +pub enum MigrateMsg +where + MigrateExt: JsonSchema, +{ + FromUnderV250 { + /// Optionally set a new submission policy with more granular controls. + /// If not set, the current policy will remain. + policy: Option, + }, + Extension { + msg: MigrateExt, + }, +} diff --git a/packages/dao-pre-propose-base/src/state.rs b/packages/dao-pre-propose-base/src/state.rs index 4967e1de9..5004cfab5 100644 --- a/packages/dao-pre-propose-base/src/state.rs +++ b/packages/dao-pre-propose-base/src/state.rs @@ -16,7 +16,7 @@ pub struct Config { pub submission_policy: PreProposeSubmissionPolicy, } -pub struct PreProposeContract { +pub struct PreProposeContract { /// The proposal module that this module is associated with. pub proposal_module: Item<'static, Addr>, /// The DAO (dao-dao-core module) that this module is associated @@ -35,11 +35,12 @@ pub struct PreProposeContract, execute_type: PhantomData, query_type: PhantomData, + migrate_type: PhantomData, proposal_type: PhantomData, } -impl - PreProposeContract +impl + PreProposeContract { const fn new( proposal_key: &'static str, @@ -57,13 +58,14 @@ impl execute_type: PhantomData, instantiate_type: PhantomData, query_type: PhantomData, + migrate_type: PhantomData, proposal_type: PhantomData, } } } -impl Default - for PreProposeContract +impl Default + for PreProposeContract { fn default() -> Self { // Call into constant function here. Presumably, the compiler diff --git a/packages/dao-pre-propose-base/src/tests.rs b/packages/dao-pre-propose-base/src/tests.rs index 89522def2..be7c4d189 100644 --- a/packages/dao-pre-propose-base/src/tests.rs +++ b/packages/dao-pre-propose-base/src/tests.rs @@ -12,7 +12,7 @@ use crate::{ state::{Config, PreProposeContract}, }; -type Contract = PreProposeContract; +type Contract = PreProposeContract; #[test] fn test_completed_hook_status_invariant() {