From fb60e8683256a139ba3c2eba202e2d4f80d11dfd Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Tue, 9 Jan 2024 00:34:41 -0800 Subject: [PATCH 01/47] Smart contract skeleton for voting incentives --- Cargo.lock | 17 ++ .../dao-voting-incentives/.cargo/config | 4 + .../external/dao-voting-incentives/Cargo.toml | 33 ++++ .../external/dao-voting-incentives/README.md | 14 ++ .../dao-voting-incentives/examples/schema.rs | 11 ++ .../schema/cw-admin-factory.json | 69 +++++++ .../dao-voting-incentives/src/contract.rs | 80 +++++++++ .../dao-voting-incentives/src/error.rs | 18 ++ .../external/dao-voting-incentives/src/lib.rs | 10 ++ .../external/dao-voting-incentives/src/msg.rs | 27 +++ .../dao-voting-incentives/src/tests.rs | 168 ++++++++++++++++++ 11 files changed, 451 insertions(+) create mode 100644 contracts/external/dao-voting-incentives/.cargo/config create mode 100644 contracts/external/dao-voting-incentives/Cargo.toml create mode 100644 contracts/external/dao-voting-incentives/README.md create mode 100644 contracts/external/dao-voting-incentives/examples/schema.rs create mode 100644 contracts/external/dao-voting-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-voting-incentives/src/contract.rs create mode 100644 contracts/external/dao-voting-incentives/src/error.rs create mode 100644 contracts/external/dao-voting-incentives/src/lib.rs create mode 100644 contracts/external/dao-voting-incentives/src/msg.rs create mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index f87706bf4..b86045daa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2129,6 +2129,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "dao-voting-incentives" +version = "2.4.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core", + "dao-hooks", + "dao-interface", + "thiserror", +] + [[package]] name = "dao-voting-token-staked" version = "2.4.0" diff --git a/contracts/external/dao-voting-incentives/.cargo/config b/contracts/external/dao-voting-incentives/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/external/dao-voting-incentives/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml new file mode 100644 index 000000000..97106c68a --- /dev/null +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name ="dao-voting-incentives" +authors = ["Jake Hartnell "] +description = "A contract that implements incentives for voting in a DAO." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +dao-hooks = { workspace = true } +dao-interface = { workspace = true } +thiserror = { workspace = true } +cw-utils = { workspace = true } + +[dev-dependencies] +cosmwasm-schema = { workspace = true } +cw-multi-test = { workspace = true } +dao-dao-core = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md new file mode 100644 index 000000000..2ee2a1d98 --- /dev/null +++ b/contracts/external/dao-voting-incentives/README.md @@ -0,0 +1,14 @@ +# cw-admin-factory + +[![cw-admin-factory on crates.io](https://img.shields.io/crates/v/cw-admin-factory.svg?logo=rust)](https://crates.io/crates/cw-admin-factory) +[![docs.rs](https://img.shields.io/docsrs/cw-admin-factory?logo=docsdotrs)](https://docs.rs/cw-admin-factory/latest/cw_admin_factory/) + +Serves as a factory that instantiates contracts and sets them as their +own wasm admins. + +Useful for allowing contracts (e.g. DAOs) to migrate themselves. + +Example instantiation flow: + +![](https://bafkreibqsrdnht5chc5mdzbb6pgiyqfjke3yvukvjrokyefwwbl3k3iwaa.ipfs.nftstorage.link) + diff --git a/contracts/external/dao-voting-incentives/examples/schema.rs b/contracts/external/dao-voting-incentives/examples/schema.rs new file mode 100644 index 000000000..52981727a --- /dev/null +++ b/contracts/external/dao-voting-incentives/examples/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; +use dao_voting_incentives::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json new file mode 100644 index 000000000..f1a1e1254 --- /dev/null +++ b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json @@ -0,0 +1,69 @@ +{ + "contract_name": "cw-admin-factory", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", + "type": "object", + "required": [ + "instantiate_contract_with_self_admin" + ], + "properties": { + "instantiate_contract_with_self_admin": { + "type": "object", + "required": [ + "code_id", + "instantiate_msg", + "label" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "instantiate_msg": { + "$ref": "#/definitions/Binary" + }, + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "type": "string", + "enum": [] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": {} +} diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs new file mode 100644 index 000000000..5ec59d86d --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -0,0 +1,80 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cw2::set_contract_version; +use dao_hooks::vote::VoteHookMsg; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const INSTANTIATE_CONTRACT_REPLY_ID: u64 = 0; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + // Save config + + // Check initial deposit + + Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("creator", info.sender)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Claim {} => unimplemented!(), + ExecuteMsg::VoteHook(msg) => unimplemented!(), + } +} + +pub fn execute_claim( + deps: DepsMut, + env: Env, + info: MessageInfo, +) -> Result { + Ok(Response::default().add_attribute("action", "claim")) +} + +pub fn execute_vote_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: VoteHookMsg, +) -> Result { + // Check epoch + + // TODO what is the best data structure to use here? + // Save vote + // Save prop ID + + Ok(Response::default().add_attribute("action", "vote_hook")) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Rewards { address } => unimplemented!(), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs new file mode 100644 index 000000000..56c764778 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::StdError; +use cw_utils::ParseReplyError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("{0}")] + ParseReplyError(#[from] ParseReplyError), + + #[error("An unknown reply ID was received.")] + UnknownReplyID {}, +} diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs new file mode 100644 index 000000000..6902586b6 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -0,0 +1,10 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +pub mod contract; +mod error; +pub mod msg; + +#[cfg(test)] +mod tests; + +pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs new file mode 100644 index 000000000..a002932b5 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -0,0 +1,27 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use dao_hooks::vote::VoteHookMsg; + +#[cw_serde] +pub struct InstantiateMsg { + /// DAO address + pub dao: String, +} + +#[cw_serde] +pub enum ExecuteMsg { + /// Fires when a new vote is cast. + VoteHook(VoteHookMsg), + /// Claim rewards. + Claim {}, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Returns the rewards for the given address. + #[returns(cosmwasm_std::Uint128)] + Rewards { address: String }, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs new file mode 100644 index 000000000..3bee180ee --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -0,0 +1,168 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, +}; + +use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use dao_interface::state::{Admin, ModuleInstantiateInfo}; + +use crate::{ + contract::instantiate, + contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, +}; + +fn factory_contract() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ) + .with_reply(crate::contract::reply); + Box::new(contract) +} + +fn cw20_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) +} + +fn cw_core_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core::contract::execute, + dao_dao_core::contract::instantiate, + dao_dao_core::contract::query, + ) + .with_reply(dao_dao_core::contract::reply) + .with_migrate(dao_dao_core::contract::migrate); + Box::new(contract) +} + +#[test] +pub fn test_set_admin() { + let mut app = App::default(); + let code_id = app.store_code(factory_contract()); + let cw20_code_id = app.store_code(cw20_contract()); + let cw20_instantiate = cw20_base::msg::InstantiateMsg { + name: "DAO".to_string(), + symbol: "DAO".to_string(), + decimals: 6, + initial_balances: vec![], + mint: None, + marketing: None, + }; + + let instantiate = InstantiateMsg {}; + let factory_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("CREATOR"), + &instantiate, + &[], + "cw-admin-factory", + None, + ) + .unwrap(); + + // Instantiate core contract using factory. + let cw_core_code_id = app.store_code(cw_core_contract()); + let instantiate_core = dao_interface::msg::InstantiateMsg { + dao_uri: None, + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that builds DAOs.".to_string(), + image_url: None, + automatically_add_cw20s: true, + automatically_add_cw721s: true, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "voting module".to_string(), + }, + proposal_modules_instantiate_info: vec![ + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module".to_string(), + }, + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module 2".to_string(), + }, + ], + initial_items: None, + }; + + let res: AppResponse = app + .execute_contract( + Addr::unchecked("CREATOR"), + factory_addr, + &ExecuteMsg::InstantiateContractWithSelfAdmin { + instantiate_msg: to_json_binary(&instantiate_core).unwrap(), + code_id: cw_core_code_id, + label: "my contract".to_string(), + }, + &[], + ) + .unwrap(); + + // Get the core address from the instantiate event + let instantiate_event = &res.events[2]; + assert_eq!(instantiate_event.ty, "instantiate"); + let core_addr = instantiate_event.attributes[0].value.clone(); + + // Check that admin of core address is itself + let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); + assert_eq!(contract_info.admin, Some(core_addr)) +} + +#[test] +pub fn test_set_admin_mock() { + let mut deps = mock_dependencies(); + // Instantiate factory contract + let instantiate_msg = InstantiateMsg {}; + let info = mock_info("creator", &[]); + let env = mock_env(); + instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); + let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; + let reply_msg: Reply = Reply { + id: INSTANTIATE_CONTRACT_REPLY_ID, + result: SubMsgResult::Ok(SubMsgResponse { + events: vec![], + data: (Some(Binary(bytes))), + }), + }; + + let res = reply(deps.as_mut(), env, reply_msg).unwrap(); + assert_eq!(res.attributes.len(), 1); + assert_eq!( + res.messages[0], + SubMsg::new(WasmMsg::UpdateAdmin { + contract_addr: "contract2".to_string(), + admin: "contract2".to_string() + }) + ) +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} From 16bfaeebf59ee0f5599dbbcca29881f1457996d0 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Mon, 22 Jan 2024 17:20:35 -0800 Subject: [PATCH 02/47] More comments --- .../external/dao-voting-incentives/src/contract.rs | 10 +++++----- contracts/external/dao-voting-incentives/src/msg.rs | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 5ec59d86d..6f10d0d09 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -9,7 +9,6 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub const INSTANTIATE_CONTRACT_REPLY_ID: u64 = 0; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -37,8 +36,8 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Claim {} => unimplemented!(), - ExecuteMsg::VoteHook(msg) => unimplemented!(), + ExecuteMsg::Claim {} => execute_claim(deps, env, info), + ExecuteMsg::VoteHook(msg) => execute_vote_hook(deps, env, info, msg), } } @@ -59,8 +58,9 @@ pub fn execute_vote_hook( // Check epoch // TODO what is the best data structure to use here? - // Save vote - // Save prop ID + // Save vote? Save prop ID? + // Save (user, epoch, vote count) + // Save (epoch, prop count) Ok(Response::default().add_attribute("action", "vote_hook")) } diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index a002932b5..67642be33 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,10 +1,13 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Timestamp; use dao_hooks::vote::VoteHookMsg; #[cw_serde] pub struct InstantiateMsg { /// DAO address pub dao: String, + /// Epoch duration in seconds. Used for reward calculation. + pub epoch_duration: Timestamp, } #[cw_serde] From bd79371427a5995b9993d6bb68c3e5a72997e2e1 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Wed, 24 Jan 2024 16:23:07 +0100 Subject: [PATCH 03/47] dao-proposal-incentives initial commit --- .../dao-proposal-incentives/.cargo/config | 4 + .../dao-proposal-incentives/Cargo.toml | 34 ++++ .../dao-proposal-incentives/README.md | 6 + .../examples/schema.rs | 11 ++ .../schema/cw-admin-factory.json | 69 +++++++ .../dao-proposal-incentives/src/contract.rs | 126 +++++++++++++ .../dao-proposal-incentives/src/error.rs | 18 ++ .../dao-proposal-incentives/src/lib.rs | 11 ++ .../dao-proposal-incentives/src/msg.rs | 37 ++++ .../dao-proposal-incentives/src/state.rs | 16 ++ .../dao-proposal-incentives/src/tests.rs | 168 ++++++++++++++++++ 11 files changed, 500 insertions(+) create mode 100644 contracts/external/dao-proposal-incentives/.cargo/config create mode 100644 contracts/external/dao-proposal-incentives/Cargo.toml create mode 100644 contracts/external/dao-proposal-incentives/README.md create mode 100644 contracts/external/dao-proposal-incentives/examples/schema.rs create mode 100644 contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-proposal-incentives/src/contract.rs create mode 100644 contracts/external/dao-proposal-incentives/src/error.rs create mode 100644 contracts/external/dao-proposal-incentives/src/lib.rs create mode 100644 contracts/external/dao-proposal-incentives/src/msg.rs create mode 100644 contracts/external/dao-proposal-incentives/src/state.rs create mode 100644 contracts/external/dao-proposal-incentives/src/tests.rs diff --git a/contracts/external/dao-proposal-incentives/.cargo/config b/contracts/external/dao-proposal-incentives/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml new file mode 100644 index 000000000..4de53d38c --- /dev/null +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name ="dao-proposal-incentives" +authors = ["Jake Hartnell "] +description = "A contract that implements incentives for voting in a DAO." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +dao-hooks = { workspace = true } +dao-interface = { workspace = true } +dao-voting = { workspace = true } +thiserror = { workspace = true } +cw-utils = { workspace = true } + +[dev-dependencies] +cosmwasm-schema = { workspace = true } +cw-multi-test = { workspace = true } +dao-dao-core = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md new file mode 100644 index 000000000..20a0f9ff4 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/README.md @@ -0,0 +1,6 @@ +# dao-proposal-incentives + +[![dao-proposal-incentives on crates.io](https://img.shields.io/crates/v/dao-proposal-incentives.svg?logo=rust)](https://crates.io/crates/dao-proposal-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) + +Allows for DAOs to offer incentives for making successful proposals. diff --git a/contracts/external/dao-proposal-incentives/examples/schema.rs b/contracts/external/dao-proposal-incentives/examples/schema.rs new file mode 100644 index 000000000..faa86b601 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/examples/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; +use dao_proposal_incentives::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json new file mode 100644 index 000000000..f1a1e1254 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json @@ -0,0 +1,69 @@ +{ + "contract_name": "cw-admin-factory", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", + "type": "object", + "required": [ + "instantiate_contract_with_self_admin" + ], + "properties": { + "instantiate_contract_with_self_admin": { + "type": "object", + "required": [ + "code_id", + "instantiate_msg", + "label" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "instantiate_msg": { + "$ref": "#/definitions/Binary" + }, + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "type": "string", + "enum": [] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": {} +} diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs new file mode 100644 index 000000000..8e01dacb3 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -0,0 +1,126 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + SubMsg, +}; +use cw2::set_contract_version; +use dao_hooks::proposal::ProposalHookMsg; +use dao_voting::status::Status; + +use crate::error::ContractError; +use crate::msg::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::{DAO, PROPOSAL_INCENTIVES}; + +pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub const REPLY_PROPOSAL_HOOK_ID: u64 = 1; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + // Save DAO, assumes the sender is the DAO + DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + + // Save proposal incentives config + PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; + + // TODO Check initial deposit contains enough funds to pay out rewards + // for at least one proposal + + Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("creator", info.sender)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::ProposalHook(msg) => execute_proposal_hook(deps, env, info, msg), + } +} + +// TODO support cw20 tokens +pub fn execute_proposal_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ProposalHookMsg, +) -> Result { + let mut payout_msgs: Vec = vec![]; + + // Check prop status and type of hook + match msg { + ProposalHookMsg::ProposalStatusChanged { new_status, .. } => { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; + + // We handle payout messages in a SubMsg so the error be caught + // if need be. This is to prevent running out of funds locking the DAO. + payout_msgs.push(SubMsg::reply_on_error( + BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![proposal_incentives.rewards_per_proposal], + }, + REPLY_PROPOSAL_HOOK_ID, + )); + } + } + _ => {} + } + + Ok(Response::default() + .add_attribute("action", "proposal_hook") + .add_submessages(payout_msgs)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Config {} => query_config(deps), + } +} + +pub fn query_config(deps: Deps) -> StdResult { + let dao = DAO.load(deps.storage)?; + let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; + + to_json_binary(&ConfigResponse { + dao, + proposal_incentives, + }) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { + match msg.id { + REPLY_PROPOSAL_HOOK_ID => { + // If an error occurred with payout, we still return an ok response + // because we don't want to fail the proposal hook and lock the DAO. + Ok(Response::default()) + } + _ => Err(ContractError::UnknownReplyID {}), + } +} diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs new file mode 100644 index 000000000..56c764778 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::StdError; +use cw_utils::ParseReplyError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("{0}")] + ParseReplyError(#[from] ParseReplyError), + + #[error("An unknown reply ID was received.")] + UnknownReplyID {}, +} diff --git a/contracts/external/dao-proposal-incentives/src/lib.rs b/contracts/external/dao-proposal-incentives/src/lib.rs new file mode 100644 index 000000000..d1800adbc --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/lib.rs @@ -0,0 +1,11 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +#[cfg(test)] +mod tests; + +pub use crate::error::ContractError; diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs new file mode 100644 index 000000000..0c714bcce --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -0,0 +1,37 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use dao_hooks::{proposal::ProposalHookMsg, vote::VoteHookMsg}; + +use crate::state::{ProposalIncentives, VotingIncentives}; + +#[cw_serde] +pub struct InstantiateMsg { + /// DAO address + pub dao: String, + /// Rewards to pay out for successful proposals. + pub proposal_incentives: ProposalIncentives, +} + +#[cw_serde] +pub enum ExecuteMsg { + /// Fires when a new proposal status has changed. + ProposalHook(ProposalHookMsg), +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Returns the config. + #[returns(ConfigResponse)] + Config {}, +} + +#[cw_serde] +pub struct ConfigResponse { + /// DAO address + pub dao: String, + /// Rewards to pay out for successful proposals. + pub proposal_incentives: ProposalIncentives, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/external/dao-proposal-incentives/src/state.rs b/contracts/external/dao-proposal-incentives/src/state.rs new file mode 100644 index 000000000..ee7c7c0af --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/state.rs @@ -0,0 +1,16 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin}; +use cw_storage_plus::Item; + +/// The address of the DAO this contract serves +pub const DAO: Item = Item::new("dao"); + +/// Incentives for passing successful proposals +#[cw_serde] +pub struct ProposalIncentives { + /// The rewards to pay out per successful proposal. + pub rewards_per_proposal: Coin, +} + +/// Holds ProposalIncentives state +pub const PROPOSAL_INCENTIVES: Item = Item::new("proposal_incentives"); diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs new file mode 100644 index 000000000..3bee180ee --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -0,0 +1,168 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, +}; + +use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use dao_interface::state::{Admin, ModuleInstantiateInfo}; + +use crate::{ + contract::instantiate, + contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, +}; + +fn factory_contract() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ) + .with_reply(crate::contract::reply); + Box::new(contract) +} + +fn cw20_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) +} + +fn cw_core_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core::contract::execute, + dao_dao_core::contract::instantiate, + dao_dao_core::contract::query, + ) + .with_reply(dao_dao_core::contract::reply) + .with_migrate(dao_dao_core::contract::migrate); + Box::new(contract) +} + +#[test] +pub fn test_set_admin() { + let mut app = App::default(); + let code_id = app.store_code(factory_contract()); + let cw20_code_id = app.store_code(cw20_contract()); + let cw20_instantiate = cw20_base::msg::InstantiateMsg { + name: "DAO".to_string(), + symbol: "DAO".to_string(), + decimals: 6, + initial_balances: vec![], + mint: None, + marketing: None, + }; + + let instantiate = InstantiateMsg {}; + let factory_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("CREATOR"), + &instantiate, + &[], + "cw-admin-factory", + None, + ) + .unwrap(); + + // Instantiate core contract using factory. + let cw_core_code_id = app.store_code(cw_core_contract()); + let instantiate_core = dao_interface::msg::InstantiateMsg { + dao_uri: None, + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that builds DAOs.".to_string(), + image_url: None, + automatically_add_cw20s: true, + automatically_add_cw721s: true, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "voting module".to_string(), + }, + proposal_modules_instantiate_info: vec![ + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module".to_string(), + }, + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module 2".to_string(), + }, + ], + initial_items: None, + }; + + let res: AppResponse = app + .execute_contract( + Addr::unchecked("CREATOR"), + factory_addr, + &ExecuteMsg::InstantiateContractWithSelfAdmin { + instantiate_msg: to_json_binary(&instantiate_core).unwrap(), + code_id: cw_core_code_id, + label: "my contract".to_string(), + }, + &[], + ) + .unwrap(); + + // Get the core address from the instantiate event + let instantiate_event = &res.events[2]; + assert_eq!(instantiate_event.ty, "instantiate"); + let core_addr = instantiate_event.attributes[0].value.clone(); + + // Check that admin of core address is itself + let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); + assert_eq!(contract_info.admin, Some(core_addr)) +} + +#[test] +pub fn test_set_admin_mock() { + let mut deps = mock_dependencies(); + // Instantiate factory contract + let instantiate_msg = InstantiateMsg {}; + let info = mock_info("creator", &[]); + let env = mock_env(); + instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); + let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; + let reply_msg: Reply = Reply { + id: INSTANTIATE_CONTRACT_REPLY_ID, + result: SubMsgResult::Ok(SubMsgResponse { + events: vec![], + data: (Some(Binary(bytes))), + }), + }; + + let res = reply(deps.as_mut(), env, reply_msg).unwrap(); + assert_eq!(res.attributes.len(), 1); + assert_eq!( + res.messages[0], + SubMsg::new(WasmMsg::UpdateAdmin { + contract_addr: "contract2".to_string(), + admin: "contract2".to_string() + }) + ) +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} From 97e24727b78fc88620425afe77908ba4555265b0 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Wed, 24 Jan 2024 16:29:13 +0100 Subject: [PATCH 04/47] Add more design notes and TODOs --- Cargo.lock | 19 ++++++++ .../external/dao-voting-incentives/Cargo.toml | 1 + .../dao-voting-incentives/src/contract.rs | 45 +++++++++++++++---- .../external/dao-voting-incentives/src/lib.rs | 1 + .../external/dao-voting-incentives/src/msg.rs | 18 ++++++-- .../dao-voting-incentives/src/state.rs | 33 ++++++++++++++ 6 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 contracts/external/dao-voting-incentives/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index b86045daa..527dced99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1842,6 +1842,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "dao-proposal-incentives" +version = "2.4.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core", + "dao-hooks", + "dao-interface", + "dao-voting 2.4.0", + "thiserror", +] + [[package]] name = "dao-proposal-multiple" version = "2.4.0" @@ -2143,6 +2161,7 @@ dependencies = [ "dao-dao-core", "dao-hooks", "dao-interface", + "dao-voting 2.4.0", "thiserror", ] diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index 97106c68a..d80c6b322 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -23,6 +23,7 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } dao-hooks = { workspace = true } dao-interface = { workspace = true } +dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 6f10d0d09..989142962 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,11 +1,12 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; use dao_hooks::vote::VoteHookMsg; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::{DAO, VOTING_INCENTIVES}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -15,13 +16,17 @@ pub fn instantiate( deps: DepsMut, _env: Env, info: MessageInfo, - _msg: InstantiateMsg, + msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save config + // Save DAO, assumes the sender is the DAO + DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; - // Check initial deposit + // Save voting incentives config + + // TODO Check initial deposit is enough to pay out rewards for at + // least one epoch Ok(Response::new() .add_attribute("method", "instantiate") @@ -41,26 +46,47 @@ pub fn execute( } } +// TODO how to claim for many epochs efficiently? pub fn execute_claim( deps: DepsMut, env: Env, info: MessageInfo, ) -> Result { + // Check epoch should advance + + // Save last claimed epoch + + // Load user vote count for epoch? + + // Load prop count for epoch + + // Load voting incentives config + let voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; + + // Need total vote count for epoch + // Rewards = (user vote count / prop count) / total_vote_count * voting incentives + + // Pay out rewards + Ok(Response::default().add_attribute("action", "claim")) } +// TODO support cw20 tokens +// TODO make sure config can't lock DAO pub fn execute_vote_hook( deps: DepsMut, env: Env, info: MessageInfo, msg: VoteHookMsg, ) -> Result { - // Check epoch + // Check epoch should advance + + // TODO need some state to handle this + // Check that the vote is not a changed vote (i.e. the user has already voted + // on the prop). - // TODO what is the best data structure to use here? - // Save vote? Save prop ID? - // Save (user, epoch, vote count) - // Save (epoch, prop count) + // Save (user, epoch), vote count + // Update (epoch, prop count) Ok(Response::default().add_attribute("action", "vote_hook")) } @@ -69,6 +95,7 @@ pub fn execute_vote_hook( pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Rewards { address } => unimplemented!(), + QueryMsg::Config {} => unimplemented!(), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index 6902586b6..d1800adbc 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -3,6 +3,7 @@ pub mod contract; mod error; pub mod msg; +pub mod state; #[cfg(test)] mod tests; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 67642be33..5298657e6 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,13 +1,14 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Timestamp; use dao_hooks::vote::VoteHookMsg; +use crate::state::VotingIncentives; + #[cw_serde] pub struct InstantiateMsg { /// DAO address pub dao: String, - /// Epoch duration in seconds. Used for reward calculation. - pub epoch_duration: Timestamp, + /// Rewards to pay out for voting. + pub voting_incentives: VotingIncentives, } #[cw_serde] @@ -21,10 +22,21 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { + /// Returns the config. + #[returns(ConfigResponse)] + Config {}, /// Returns the rewards for the given address. #[returns(cosmwasm_std::Uint128)] Rewards { address: String }, } +#[cw_serde] +pub struct ConfigResponse { + /// DAO address + pub dao: String, + /// Rewards to pay out for voting. + pub voting_incentives: VotingIncentives, +} + #[cw_serde] pub struct MigrateMsg {} diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs new file mode 100644 index 000000000..730cd7fe3 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -0,0 +1,33 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin, Timestamp}; +use cw_storage_plus::{Item, Map}; + +/// The address of the DAO this contract serves +pub const DAO: Item = Item::new("dao"); + +/// Incentives for voting +#[cw_serde] +pub struct VotingIncentives { + /// Epoch duration in seconds. Used for reward calculation. + pub epoch_duration: Timestamp, + /// The rewards to pay out per epoch. + pub rewards_per_epoch: Coin, +} + +/// Holds VotingIncentives state +pub const VOTING_INCENTIVES: Item = Item::new("voting_incentives"); + +/// The current epoch +pub const EPOCH: Item = Item::new("epoch"); + +/// A map of addresses to their last claimed epoch +pub const LAST_CLAIMED_EPOCHS: Map = Map::new("last_claimed_epoch"); + +/// A map of epochs to prop count +pub const EPOCH_PROPOSAL_COUNT: Map = Map::new("epoch_proposal_count"); + +/// A map of epochs to total vote count +pub const EPOCH_TOTAL_VOTE_COUNT: Map = Map::new("epoch_total_vote_count"); + +/// A map of user addresses + epoch to vote count +pub const USER_EPOCH_VOTE_COUNT: Map<(Addr, u64), u64> = Map::new("user_epoch_vote_count"); From c1ef0bf30403a62613d012c7ec534ec37f2c530b Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 15:57:30 +0100 Subject: [PATCH 05/47] Proposal incentives fixups and notes --- .../external/dao-proposal-incentives/README.md | 7 +++++++ .../dao-proposal-incentives/src/contract.rs | 14 +++++++++++--- .../external/dao-proposal-incentives/src/error.rs | 14 ++++++++++---- .../external/dao-proposal-incentives/src/msg.rs | 4 ++-- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 20a0f9ff4..de17171b8 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -4,3 +4,10 @@ [![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) Allows for DAOs to offer incentives for making successful proposals. + +To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When someone successfully passes a proposal the specified rewards are automatically paid out. + +## TODO +- [ ] Unit and Integration tests with a full DAO +- [ ] Support Cw20 +- [ ] Add more info to the readme and delete this TODO section diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs index 8e01dacb3..5e7cabcea 100644 --- a/contracts/external/dao-proposal-incentives/src/contract.rs +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -5,6 +5,7 @@ use cosmwasm_std::{ SubMsg, }; use cw2::set_contract_version; +use cw_utils::must_pay; use dao_hooks::proposal::ProposalHookMsg; use dao_voting::status::Status; @@ -32,8 +33,15 @@ pub fn instantiate( // Save proposal incentives config PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; - // TODO Check initial deposit contains enough funds to pay out rewards + // Check initial deposit contains enough funds to pay out rewards // for at least one proposal + let amount = must_pay(&info, &msg.proposal_incentives.rewards_per_proposal.denom)?; + if amount < msg.proposal_incentives.rewards_per_proposal.amount { + return Err(ContractError::InsufficientInitialDeposit { + expected: msg.proposal_incentives.rewards_per_proposal.amount, + actual: amount, + }); + }; Ok(Response::new() .add_attribute("method", "instantiate") @@ -55,7 +63,7 @@ pub fn execute( // TODO support cw20 tokens pub fn execute_proposal_hook( deps: DepsMut, - env: Env, + _env: Env, info: MessageInfo, msg: ProposalHookMsg, ) -> Result { @@ -101,7 +109,7 @@ pub fn query_config(deps: Deps) -> StdResult { let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; to_json_binary(&ConfigResponse { - dao, + dao: dao.to_string(), proposal_incentives, }) } diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index 56c764778..69d218ddc 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -1,5 +1,5 @@ -use cosmwasm_std::StdError; -use cw_utils::ParseReplyError; +use cosmwasm_std::{StdError, Uint128}; +use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; #[derive(Error, Debug)] @@ -7,12 +7,18 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, + #[error("{0}")] + PaymentError(#[from] PaymentError), + + #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] + InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("Unauthorized")] + Unauthorized {}, + #[error("An unknown reply ID was received.")] UnknownReplyID {}, } diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs index 0c714bcce..d3290bbde 100644 --- a/contracts/external/dao-proposal-incentives/src/msg.rs +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use dao_hooks::{proposal::ProposalHookMsg, vote::VoteHookMsg}; +use dao_hooks::proposal::ProposalHookMsg; -use crate::state::{ProposalIncentives, VotingIncentives}; +use crate::state::ProposalIncentives; #[cw_serde] pub struct InstantiateMsg { From a7bb852c9b201d30cff5c307e3b22f05d33bc8cb Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 15:57:50 +0100 Subject: [PATCH 06/47] Voting incentives checks and notes --- .../external/dao-voting-incentives/README.md | 25 +++++++++++++------ .../dao-voting-incentives/src/contract.rs | 14 ++++++++--- .../dao-voting-incentives/src/error.rs | 16 ++++++++---- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index 2ee2a1d98..5da24b99b 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,14 +1,23 @@ -# cw-admin-factory +# dao-voting-incentives -[![cw-admin-factory on crates.io](https://img.shields.io/crates/v/cw-admin-factory.svg?logo=rust)](https://crates.io/crates/cw-admin-factory) -[![docs.rs](https://img.shields.io/docsrs/cw-admin-factory?logo=docsdotrs)](https://docs.rs/cw-admin-factory/latest/cw_admin_factory/) +[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) -Serves as a factory that instantiates contracts and sets them as their -own wasm admins. +Allows for DAOs to offer incentives for voting on DAO proposals. -Useful for allowing contracts (e.g. DAOs) to migrate themselves. +When creating this contract, the DAO specifies an `epoch_duration` and an amount to pay out per epoch. Then, the DAO needs to add this contract as a `VoteHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When DAO members vote, this contract keeps track of the proposals and who voted. -Example instantiation flow: +At the end of the epoch, rewards are payable as follows: -![](https://bafkreibqsrdnht5chc5mdzbb6pgiyqfjke3yvukvjrokyefwwbl3k3iwaa.ipfs.nftstorage.link) +``` +rewards = (user vote count / prop count) / total_vote_count * voting incentives +``` +If no proposals happen during an epoch, no rewards are paid out. + +## TODO +- [ ] Unit and Integration tests with a full DAO +- [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) +- [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. +- [ ] Support Cw20. +- [ ] Add more info to the readme and delete this TODO section. diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 989142962..28ff99777 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -2,6 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; +use cw_utils::must_pay; use dao_hooks::vote::VoteHookMsg; use crate::error::ContractError; @@ -24,9 +25,16 @@ pub fn instantiate( DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; // Save voting incentives config - - // TODO Check initial deposit is enough to pay out rewards for at - // least one epoch + VOTING_INCENTIVES.save(deps.storage, &msg.voting_incentives)?; + + // Check initial deposit is enough to pay out rewards for at least one epoch + let amount = must_pay(&info, &msg.voting_incentives.rewards_per_epoch.denom)?; + if amount < msg.voting_incentives.rewards_per_epoch.amount { + return Err(ContractError::InsufficientInitialDeposit { + expected: msg.voting_incentives.rewards_per_epoch.amount, + actual: amount, + }); + }; Ok(Response::new() .add_attribute("method", "instantiate") diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 56c764778..2b1469dcb 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -1,5 +1,5 @@ -use cosmwasm_std::StdError; -use cw_utils::ParseReplyError; +use cosmwasm_std::{StdError, Uint128}; +use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; #[derive(Error, Debug)] @@ -7,12 +7,18 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("{0}")] + PaymentError(#[from] PaymentError), + + #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] + InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + + #[error("Unauthorized")] + Unauthorized {}, + #[error("An unknown reply ID was received.")] UnknownReplyID {}, } From 21c488bc91aacfe870c5f00a0ceb5a1b9dd75e40 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 16:00:52 +0100 Subject: [PATCH 07/47] More notes --- contracts/external/dao-proposal-incentives/README.md | 1 + contracts/external/dao-voting-incentives/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index de17171b8..7fea7973b 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -10,4 +10,5 @@ To setup this contract, the DAO needs to add this contract as a `ProposalHook` t ## TODO - [ ] Unit and Integration tests with a full DAO - [ ] Support Cw20 +- [ ] Use `cw-ownable` to configure a contract owner who can update the proposal incentives config. - [ ] Add more info to the readme and delete this TODO section diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index 5da24b99b..f41943baf 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -20,4 +20,5 @@ If no proposals happen during an epoch, no rewards are paid out. - [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) - [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. - [ ] Support Cw20. +- [ ] Use `cw-ownable` to configure a contract owner who can update the voting incentives config. - [ ] Add more info to the readme and delete this TODO section. From b7b01cb63b662900966903cb6a75dadce2ead5b6 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 10:33:44 -0600 Subject: [PATCH 08/47] Proposal Incentives --- Cargo.lock | 405 +++++++------- Cargo.toml | 1 + contracts/dao-dao-core/src/contract.rs | 8 + .../dao-proposal-incentives/Cargo.toml | 8 +- .../dao-proposal-incentives/README.md | 8 +- .../dao-proposal-incentives/src/contract.rs | 113 +--- .../dao-proposal-incentives/src/error.rs | 14 +- .../dao-proposal-incentives/src/execute.rs | 112 ++++ .../dao-proposal-incentives/src/helpers.rs | 31 + .../dao-proposal-incentives/src/lib.rs | 3 + .../dao-proposal-incentives/src/msg.rs | 34 +- .../dao-proposal-incentives/src/query.rs | 14 + .../dao-proposal-incentives/src/state.rs | 18 +- .../dao-proposal-incentives/src/tests.rs | 528 ++++++++++++++---- .../external/dao-voting-incentives/Cargo.toml | 1 + .../dao-voting-incentives/src/contract.rs | 2 +- .../dao-voting-incentives/src/tests.rs | 167 ------ .../dao-proposal-condorcet/src/contract.rs | 1 + .../dao-proposal-multiple/src/contract.rs | 7 + .../dao-proposal-multiple/src/proposal.rs | 8 + .../proposal/dao-proposal-single/Cargo.toml | 1 + .../dao-proposal-single/src/contract.rs | 7 + .../dao-proposal-single/src/proposal.rs | 8 + packages/dao-dao-macros/src/lib.rs | 3 + packages/dao-dao-macros/tests/govmod.rs | 1 + packages/dao-hooks/src/proposal.rs | 2 +- packages/dao-interface/src/msg.rs | 3 + packages/dao-interface/src/proposal.rs | 11 + packages/dao-testing/Cargo.toml | 1 + packages/dao-testing/src/contracts.rs | 10 + 30 files changed, 923 insertions(+), 607 deletions(-) create mode 100644 contracts/external/dao-proposal-incentives/src/execute.rs create mode 100644 contracts/external/dao-proposal-incentives/src/helpers.rs create mode 100644 contracts/external/dao-proposal-incentives/src/query.rs diff --git a/Cargo.lock b/Cargo.lock index 527dced99..7a027be43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "assert_matches" @@ -68,18 +68,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -168,9 +168,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -190,7 +190,7 @@ version = "0.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cexpr", "clang-sys", "lazy_static", @@ -203,7 +203,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.48", "which", ] @@ -233,9 +233,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block-buffer" @@ -340,18 +340,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "num-traits", ] [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -379,9 +379,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation" @@ -510,32 +510,32 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" dependencies = [ "digest 0.10.7", "ecdsa 0.16.9", "ed25519-zebra", - "k256 0.13.2", + "k256 0.13.3", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" +checksum = "40abec852f3d4abec6d44ead9a58b78325021a1ead1e7229c3471414e57b2e49" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df41ea55f2946b6b43579659eec048cc2f66e8c8e2e3652fc5e5e476f673856" +checksum = "b166215fbfe93dc5575bae062aa57ae7bb41121cffe53bac33b033257949d2a9" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43609e92ce1b9368aa951b334dd354a2d0dd4d484931a5f83ae10e12a26c8ba9" +checksum = "8bf12f8e20bb29d1db66b7ca590bc2f670b548d21e9be92499bc0f9022a994a8" dependencies = [ "proc-macro2", "quote", @@ -557,11 +557,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d6864742e3a7662d024b51a94ea81c9af21db6faea2f9a6d2232bb97c6e53e" +checksum = "ad011ae7447188e26e4a7dbca2fcd0fc186aa21ae5c86df0503ea44c78f9e469" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bech32", "bnum", "cosmwasm-crypto", @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd2b4ae72a03e8f56c85df59d172d51d2d7dc9cec6e2bc811e3fb60c588032a4" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -589,9 +589,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1848,14 +1848,20 @@ version = "2.4.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-denom", + "cw-hooks", "cw-multi-test", + "cw-ownable", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", + "cw20 1.1.2", "cw20-base 1.1.2", "dao-dao-core", "dao-hooks", "dao-interface", + "dao-proposal-single", + "dao-testing", "dao-voting 2.4.0", "thiserror", ] @@ -1924,6 +1930,7 @@ dependencies = [ "dao-interface", "dao-pre-propose-base", "dao-pre-propose-single", + "dao-proposal-incentives", "dao-testing", "dao-voting 0.1.0", "dao-voting 2.4.0", @@ -1995,6 +2002,7 @@ dependencies = [ "dao-pre-propose-multiple", "dao-pre-propose-single", "dao-proposal-condorcet", + "dao-proposal-incentives", "dao-proposal-single", "dao-test-custom-factory", "dao-voting 0.1.0", @@ -2153,6 +2161,7 @@ version = "2.4.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-hooks", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -2367,9 +2376,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -2405,9 +2414,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" dependencies = [ "indenter", "once_cell", @@ -2466,9 +2475,9 @@ checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -2481,9 +2490,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -2491,15 +2500,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -2508,38 +2517,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -2566,9 +2575,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -2613,9 +2622,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -2623,7 +2632,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.1", "slab", "tokio", "tokio-util", @@ -2651,7 +2660,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "headers-core", "http", @@ -2671,9 +2680,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -2692,11 +2701,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2712,9 +2721,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -2741,9 +2750,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -2756,7 +2765,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", @@ -2853,9 +2862,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2897,13 +2906,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2926,15 +2935,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -2965,9 +2974,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa 0.16.9", @@ -2979,9 +2988,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -3000,18 +3009,18 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -3022,9 +3031,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" @@ -3040,9 +3049,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mime" @@ -3067,9 +3076,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -3127,18 +3136,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -3197,7 +3206,7 @@ version = "20.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bindgen", "cosmrs 0.9.0", "cosmwasm-std", @@ -3271,9 +3280,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" dependencies = [ "memchr", "thiserror", @@ -3282,9 +3291,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" dependencies = [ "pest", "pest_generator", @@ -3292,22 +3301,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" dependencies = [ "once_cell", "pest", @@ -3316,22 +3325,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3374,19 +3383,19 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -3446,7 +3455,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3469,9 +3478,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -3514,9 +3523,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -3526,9 +3535,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -3632,11 +3641,11 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -3676,9 +3685,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -3691,11 +3700,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3785,15 +3794,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -3809,31 +3818,31 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" dependencies = [ "serde", ] [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3849,9 +3858,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -3860,22 +3869,22 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "serde_yaml" -version = "0.9.27" +version = "0.9.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.1", "itoa", "ryu", "serde", @@ -3929,9 +3938,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signature" @@ -3962,16 +3971,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.5" @@ -4100,9 +4099,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -4328,9 +4327,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -4374,22 +4373,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4426,9 +4425,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -4436,7 +4435,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -4459,7 +4458,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4547,7 +4546,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-core", "futures-util", @@ -4618,7 +4617,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4642,9 +4641,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" @@ -4660,9 +4659,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4681,9 +4680,9 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "untrusted" @@ -4753,9 +4752,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4763,24 +4762,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4788,28 +4787,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -5047,5 +5046,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] diff --git a/Cargo.toml b/Cargo.toml index 43c0e83bf..634c38d94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,6 +105,7 @@ dao-pre-propose-multiple = { path = "./contracts/pre-propose/dao-pre-propose-mul dao-pre-propose-single = { path = "./contracts/pre-propose/dao-pre-propose-single", version = "2.4.0" } dao-proposal-condorcet = { path = "./contracts/proposal/dao-proposal-condorcet", version = "2.4.0" } dao-proposal-hook-counter = { path = "./contracts/test/dao-proposal-hook-counter", version = "2.4.0" } +dao-proposal-incentives = { path = "./contracts/external/dao-proposal-incentives", version = "2.4.0" } dao-proposal-multiple = { path = "./contracts/proposal/dao-proposal-multiple", version = "2.4.0" } dao-proposal-single = { path = "./contracts/proposal/dao-proposal-single", version = "2.4.0" } dao-proposal-sudo = { path = "./contracts/test/dao-proposal-sudo", version = "2.4.0" } diff --git a/contracts/dao-dao-core/src/contract.rs b/contracts/dao-dao-core/src/contract.rs index 56cd5c526..b41329aff 100644 --- a/contracts/dao-dao-core/src/contract.rs +++ b/contracts/dao-dao-core/src/contract.rs @@ -561,6 +561,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalModules { start_after, limit } => { query_proposal_modules(deps, start_after, limit) } + QueryMsg::ProposalModule { address } => query_proposal_module(deps, address), QueryMsg::ProposalModuleCount {} => query_proposal_module_count(deps), QueryMsg::TotalPowerAtHeight { height } => query_total_power_at_height(deps, height), QueryMsg::VotingModule {} => query_voting_module(deps), @@ -577,6 +578,13 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } } +pub fn query_proposal_module(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + let proposal_module = &PROPOSAL_MODULES.load(deps.storage, address)?; + + to_json_binary(&proposal_module) +} + pub fn query_admin(deps: Deps) -> StdResult { let admin = ADMIN.load(deps.storage)?; to_json_binary(&admin) diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index 4de53d38c..ff3827b82 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-proposal-incentives" -authors = ["Jake Hartnell "] +authors = ["Jake Hartnell ", "ismellike"] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } @@ -26,9 +26,15 @@ dao-interface = { workspace = true } dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } +cw-denom = { workspace = true } +cw-ownable = { workspace = true } +cw20 = { workspace = true } [dev-dependencies] cosmwasm-schema = { workspace = true } cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } +dao-testing = { workspace = true } +dao-proposal-single = { workspace = true, features = ["library"] } +cw-hooks = { workspace = true } \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 7fea7973b..106344544 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -5,10 +5,6 @@ Allows for DAOs to offer incentives for making successful proposals. -To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When someone successfully passes a proposal the specified rewards are automatically paid out. +To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module, and the DAO must be the `owner` of this contract. When someone successfully passes a proposal the specified rewards are automatically paid out. -## TODO -- [ ] Unit and Integration tests with a full DAO -- [ ] Support Cw20 -- [ ] Use `cw-ownable` to configure a contract owner who can update the proposal incentives config. -- [ ] Add more info to the readme and delete this TODO section +The incentives can be configured as native or cw20 tokens, and the award is determined by the configuration at the passed proposal's `start_time`. \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs index 5e7cabcea..c8fc6ff73 100644 --- a/contracts/external/dao-proposal-incentives/src/contract.rs +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -1,51 +1,39 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, - SubMsg, -}; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; -use cw_utils::must_pay; -use dao_hooks::proposal::ProposalHookMsg; -use dao_voting::status::Status; +use cw_ownable::get_ownership; -use crate::error::ContractError; -use crate::msg::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{DAO, PROPOSAL_INCENTIVES}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::PROPOSAL_INCENTIVES; +use crate::{execute, query, ContractError}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub const REPLY_PROPOSAL_HOOK_ID: u64 = 1; - #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save DAO, assumes the sender is the DAO - DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + // Save ownership + let ownership = cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; - // Save proposal incentives config - PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; + // Validate proposal incentives + let proposal_incentives = msg.proposal_incentives.into_checked(deps.as_ref())?; - // Check initial deposit contains enough funds to pay out rewards - // for at least one proposal - let amount = must_pay(&info, &msg.proposal_incentives.rewards_per_proposal.denom)?; - if amount < msg.proposal_incentives.rewards_per_proposal.amount { - return Err(ContractError::InsufficientInitialDeposit { - expected: msg.proposal_incentives.rewards_per_proposal.amount, - actual: amount, - }); - }; + // Save proposal incentives config + PROPOSAL_INCENTIVES.save(deps.storage, &proposal_incentives, env.block.height)?; Ok(Response::new() .add_attribute("method", "instantiate") - .add_attribute("creator", info.sender)) + .add_attribute("creator", info.sender) + .add_attributes(ownership.into_attributes()) + .add_attributes(proposal_incentives.into_attributes())) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -56,79 +44,30 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::ProposalHook(msg) => execute_proposal_hook(deps, env, info, msg), - } -} - -// TODO support cw20 tokens -pub fn execute_proposal_hook( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: ProposalHookMsg, -) -> Result { - let mut payout_msgs: Vec = vec![]; - - // Check prop status and type of hook - match msg { - ProposalHookMsg::ProposalStatusChanged { new_status, .. } => { - // If prop status is success, add message to pay out rewards - // Otherwise, do nothing - if new_status == Status::Passed.to_string() { - // Load proposal incentives config - let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; - - // We handle payout messages in a SubMsg so the error be caught - // if need be. This is to prevent running out of funds locking the DAO. - payout_msgs.push(SubMsg::reply_on_error( - BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![proposal_incentives.rewards_per_proposal], - }, - REPLY_PROPOSAL_HOOK_ID, - )); - } + ExecuteMsg::ProposalHook(msg) => execute::proposal_hook(deps, env, info, msg), + ExecuteMsg::UpdateOwnership(action) => execute::update_ownership(deps, env, info, action), + ExecuteMsg::UpdateProposalIncentives { + proposal_incentives, + } => execute::update_proposal_incentives(deps, env, info, proposal_incentives), + ExecuteMsg::Receive(cw20_receive_msg) => { + execute::receive_cw20(deps, env, info, cw20_receive_msg) } - _ => {} } - - Ok(Response::default() - .add_attribute("action", "proposal_hook") - .add_submessages(payout_msgs)) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => query_config(deps), + QueryMsg::ProposalIncentives { height } => { + to_json_binary(&query::proposal_incentives(deps, height)?) + } + QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), } } -pub fn query_config(deps: Deps) -> StdResult { - let dao = DAO.load(deps.storage)?; - let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; - - to_json_binary(&ConfigResponse { - dao: dao.to_string(), - proposal_incentives, - }) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { // Set contract to version to latest set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) } - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { - match msg.id { - REPLY_PROPOSAL_HOOK_ID => { - // If an error occurred with payout, we still return an ok response - // because we don't want to fail the proposal hook and lock the DAO. - Ok(Response::default()) - } - _ => Err(ContractError::UnknownReplyID {}), - } -} diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index 69d218ddc..ee3ba8822 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -1,4 +1,6 @@ -use cosmwasm_std::{StdError, Uint128}; +use cosmwasm_std::StdError; +use cw_denom::DenomError; +use cw_ownable::OwnershipError; use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; @@ -10,15 +12,21 @@ pub enum ContractError { #[error("{0}")] PaymentError(#[from] PaymentError), - #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] - InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + #[error("{0}")] + DenomError(#[from] DenomError), #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("{0}")] + OwnershipError(#[from] OwnershipError), + #[error("Unauthorized")] Unauthorized {}, #[error("An unknown reply ID was received.")] UnknownReplyID {}, + + #[error("No reward per proposal given")] + NoRewardPerProposal {}, } diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs new file mode 100644 index 000000000..b7d30dfe4 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -0,0 +1,112 @@ +use cosmwasm_std::{Attribute, CosmosMsg, DepsMut, Env, MessageInfo, Response}; +use cw20::Cw20ReceiveMsg; +use cw_ownable::{assert_owner, get_ownership}; +use dao_hooks::proposal::ProposalHookMsg; +use dao_interface::{proposal::GenericProposalInfo, state::ProposalModule}; +use dao_voting::status::Status; + +use crate::{msg::ProposalIncentivesUnchecked, state::PROPOSAL_INCENTIVES, ContractError}; + +pub fn proposal_hook( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ProposalHookMsg, +) -> Result { + let mut msgs: Vec = vec![]; + let mut attrs: Vec = vec![]; + + // Get ownership + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + // Validate the message is coming from a proposal module of the owner (DAO) + deps.querier.query_wasm_smart::( + owner, + &dao_interface::msg::QueryMsg::ProposalModule { + address: info.sender.to_string(), + }, + )?; + + // Check prop status and type of hook + match msg { + ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } => { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Query for the proposal + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender, + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, + )?; + + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, proposal_info.start_height)?; + + // Append the message if found + if let Some(proposal_incentives) = proposal_incentives { + msgs.push(proposal_incentives.denom.get_transfer_to_message( + &proposal_info.proposer, + proposal_incentives.rewards_per_proposal, + )?); + attrs = proposal_incentives.into_attributes(); + attrs.push(Attribute { + key: "proposer".to_string(), + value: proposal_info.proposer.to_string(), + }); + } + } + } + _ => {} + } + } + + Ok(Response::default() + .add_attribute("action", "proposal_hook") + .add_attributes(attrs) + .add_messages(msgs)) +} + +pub fn update_ownership( + deps: DepsMut, + env: Env, + info: MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + + Ok(Response::new() + .add_attribute("action", "update_ownership") + .add_attributes(ownership.into_attributes())) +} + +pub fn update_proposal_incentives( + deps: DepsMut, + env: Env, + info: MessageInfo, + proposal_incentives: ProposalIncentivesUnchecked, +) -> Result { + assert_owner(deps.storage, &info.sender)?; + + // Validate proposal incentives + let proposal_incentives = proposal_incentives.into_checked(deps.as_ref())?; + + // Save the new proposal incentives + PROPOSAL_INCENTIVES.save(deps.storage, &proposal_incentives, env.block.height)?; + + Ok(Response::new() + .add_attribute("action", "update_proposal_incentives") + .add_attributes(proposal_incentives.into_attributes())) +} + +pub fn receive_cw20( + _deps: DepsMut, + _env: Env, + info: MessageInfo, + _cw20_receive_msg: Cw20ReceiveMsg, +) -> Result { + Ok(Response::new() + .add_attribute("action", "receive_cw20") + .add_attribute("cw20", info.sender)) +} diff --git a/contracts/external/dao-proposal-incentives/src/helpers.rs b/contracts/external/dao-proposal-incentives/src/helpers.rs new file mode 100644 index 000000000..fa3932a88 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/helpers.rs @@ -0,0 +1,31 @@ +use cosmwasm_std::{Attribute, Deps}; + +use crate::{msg::ProposalIncentivesUnchecked, state::ProposalIncentives, ContractError}; + +impl ProposalIncentivesUnchecked { + pub fn into_checked(self, deps: Deps) -> Result { + if self.rewards_per_proposal.is_zero() { + return Err(ContractError::NoRewardPerProposal {}); + } + + Ok(ProposalIncentives { + rewards_per_proposal: self.rewards_per_proposal, + denom: self.denom.into_checked(deps)?, + }) + } +} + +impl ProposalIncentives { + pub fn into_attributes(&self) -> Vec { + vec![ + Attribute { + key: "reward_per_proposal".to_string(), + value: self.rewards_per_proposal.to_string(), + }, + Attribute { + key: "denom".to_string(), + value: self.denom.to_string(), + }, + ] + } +} diff --git a/contracts/external/dao-proposal-incentives/src/lib.rs b/contracts/external/dao-proposal-incentives/src/lib.rs index d1800adbc..9bb953dba 100644 --- a/contracts/external/dao-proposal-incentives/src/lib.rs +++ b/contracts/external/dao-proposal-incentives/src/lib.rs @@ -2,7 +2,10 @@ pub mod contract; mod error; +pub mod execute; +mod helpers; pub mod msg; +pub mod query; pub mod state; #[cfg(test)] diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs index d3290bbde..cb6f74186 100644 --- a/contracts/external/dao-proposal-incentives/src/msg.rs +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -1,37 +1,47 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Uint128; +use cw20::Cw20ReceiveMsg; +use cw_denom::UncheckedDenom; +use cw_ownable::cw_ownable_query; use dao_hooks::proposal::ProposalHookMsg; use crate::state::ProposalIncentives; #[cw_serde] pub struct InstantiateMsg { - /// DAO address - pub dao: String, + /// The contract's owner using cw-ownable + pub owner: String, /// Rewards to pay out for successful proposals. - pub proposal_incentives: ProposalIncentives, + pub proposal_incentives: ProposalIncentivesUnchecked, } #[cw_serde] pub enum ExecuteMsg { /// Fires when a new proposal status has changed. ProposalHook(ProposalHookMsg), + UpdateOwnership(cw_ownable::Action), + UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked, + }, + Receive(Cw20ReceiveMsg), } +#[cw_ownable_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - /// Returns the config. - #[returns(ConfigResponse)] - Config {}, + /// Returns the proposal incentives + #[returns(ProposalIncentives)] + ProposalIncentives { height: Option }, } #[cw_serde] -pub struct ConfigResponse { - /// DAO address - pub dao: String, - /// Rewards to pay out for successful proposals. - pub proposal_incentives: ProposalIncentives, +pub struct ProposalIncentivesUnchecked { + pub rewards_per_proposal: Uint128, + pub denom: UncheckedDenom, } #[cw_serde] -pub struct MigrateMsg {} +pub enum MigrateMsg { + FromCompatible {}, +} diff --git a/contracts/external/dao-proposal-incentives/src/query.rs b/contracts/external/dao-proposal-incentives/src/query.rs new file mode 100644 index 000000000..5e53dceec --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/query.rs @@ -0,0 +1,14 @@ +use cosmwasm_std::{Deps, StdResult}; + +use crate::state::{ProposalIncentives, PROPOSAL_INCENTIVES}; + +pub fn proposal_incentives(deps: Deps, height: Option) -> StdResult { + match height { + Some(height) => PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, height)? + .ok_or(cosmwasm_std::StdError::NotFound { + kind: "Proposal Incentives".to_string(), + }), + None => PROPOSAL_INCENTIVES.load(deps.storage), + } +} diff --git a/contracts/external/dao-proposal-incentives/src/state.rs b/contracts/external/dao-proposal-incentives/src/state.rs index ee7c7c0af..4dffda609 100644 --- a/contracts/external/dao-proposal-incentives/src/state.rs +++ b/contracts/external/dao-proposal-incentives/src/state.rs @@ -1,16 +1,20 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin}; -use cw_storage_plus::Item; - -/// The address of the DAO this contract serves -pub const DAO: Item = Item::new("dao"); +use cosmwasm_std::Uint128; +use cw_denom::CheckedDenom; +use cw_storage_plus::{SnapshotItem, Strategy}; /// Incentives for passing successful proposals #[cw_serde] pub struct ProposalIncentives { /// The rewards to pay out per successful proposal. - pub rewards_per_proposal: Coin, + pub rewards_per_proposal: Uint128, + pub denom: CheckedDenom, } /// Holds ProposalIncentives state -pub const PROPOSAL_INCENTIVES: Item = Item::new("proposal_incentives"); +pub const PROPOSAL_INCENTIVES: SnapshotItem = SnapshotItem::new( + "proposal_incentives", + "proposal_incentives__check", + "proposal_incentives__change", + Strategy::EveryBlock, +); diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 3bee180ee..340952ab1 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -1,30 +1,41 @@ use std::vec; use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, + testing::{mock_dependencies, mock_env}, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Uint128, WasmMsg, }; -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; -use dao_interface::state::{Admin, ModuleInstantiateInfo}; +use cw20::Cw20Coin; +use cw_denom::{CheckedDenom, UncheckedDenom}; +use cw_multi_test::{ + error::AnyResult, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, +}; +use cw_ownable::Ownership; +use dao_testing::{ + contracts::{dao_proposal_incentives_contract, proposal_single_contract}, + helpers::instantiate_with_cw4_groups_governance, +}; +use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; use crate::{ - contract::instantiate, - contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, - msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, + contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, ProposalIncentivesUnchecked, QueryMsg}, + state::ProposalIncentives, }; -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) +const ADMIN: &str = "admin"; +const ADDR1: &str = "addr1"; +const DENOM: &str = "juno"; + +struct Context { + app: App, + cw20_addr: Addr, + proposal_single_addr: Addr, + dao_addr: Addr, + dao_proposal_incentives_code_id: u64, } -fn cw20_contract() -> Box> { +fn cw20_base_contract() -> Box> { let contract = ContractWrapper::new( cw20_base::contract::execute, cw20_base::contract::instantiate, @@ -33,135 +44,414 @@ fn cw20_contract() -> Box> { Box::new(contract) } -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} +fn get_context() -> Context { + // Set up app with native balances + let mut app = AppBuilder::default().build(|router, _, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked(ADMIN), + vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + }); -#[test] -pub fn test_set_admin() { - let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); - let cw20_instantiate = cw20_base::msg::InstantiateMsg { - name: "DAO".to_string(), - symbol: "DAO".to_string(), - decimals: 6, - initial_balances: vec![], - mint: None, - marketing: None, - }; - - let instantiate = InstantiateMsg {}; - let factory_addr = app + // Set up cw20 with balances + let cw20_code_id = app.store_code(cw20_base_contract()); + let cw20_addr = app .instantiate_contract( - code_id, - Addr::unchecked("CREATOR"), - &instantiate, + cw20_code_id, + Addr::unchecked(ADMIN), + &cw20_base::msg::InstantiateMsg { + name: "cw20 token".to_string(), + symbol: "cwtoken".to_string(), + decimals: 6, + initial_balances: vec![Cw20Coin { + address: ADMIN.to_string(), + amount: Uint128::new(1000), + }], + mint: None, + marketing: None, + }, &[], - "cw-admin-factory", + "cw20-base", None, ) .unwrap(); - // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); - let instantiate_core = dao_interface::msg::InstantiateMsg { - dao_uri: None, - admin: None, - name: "DAO DAO".to_string(), - description: "A DAO that builds DAOs.".to_string(), - image_url: None, - automatically_add_cw20s: true, - automatically_add_cw721s: true, - voting_module_instantiate_info: ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "voting module".to_string(), - }, - proposal_modules_instantiate_info: vec![ - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module".to_string(), + // Set up dao + let proposal_single_code_id = app.store_code(proposal_single_contract()); + let dao_addr = instantiate_with_cw4_groups_governance( + &mut app, + proposal_single_code_id, + to_json_binary(&dao_proposal_single::msg::InstantiateMsg { + threshold: Threshold::AbsolutePercentage { + percentage: dao_voting::threshold::PercentageThreshold::Majority {}, }, - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module 2".to_string(), + max_voting_period: cw_utils::Duration::Height(10u64), + min_voting_period: None, + only_members_execute: false, + allow_revoting: false, + pre_propose_info: dao_voting::pre_propose::PreProposeInfo::AnyoneMayPropose {}, + close_proposal_on_execution_failure: true, + veto: None, + }) + .unwrap(), + Some(vec![Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::one(), + }]), + ); + + // Get proposal single addr + let proposal_modules: Vec = app + .wrap() + .query_wasm_smart( + dao_addr.clone(), + &dao_interface::msg::QueryMsg::ProposalModules { + start_after: None, + limit: Some(1u32), }, - ], - initial_items: None, - }; + ) + .unwrap(); + assert!(!proposal_modules.is_empty()); + let proposal_single_addr = proposal_modules.first().unwrap().address.clone(); + + // Set up dao proposal incentives code id + let dao_proposal_incentives_code_id = app.store_code(dao_proposal_incentives_contract()); + + Context { + app, + cw20_addr, + dao_addr, + dao_proposal_incentives_code_id, + proposal_single_addr, + } +} + +fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> AnyResult { + context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &vec![], + ) +} - let res: AppResponse = app +fn execute_proposal(context: &mut Context, proposal_id: u64) { + context + .app .execute_contract( - Addr::unchecked("CREATOR"), - factory_addr, - &ExecuteMsg::InstantiateContractWithSelfAdmin { - instantiate_msg: to_json_binary(&instantiate_core).unwrap(), - code_id: cw_core_code_id, - label: "my contract".to_string(), + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Execute { proposal_id }, + &vec![], + ) + .unwrap(); +} + +#[test] +pub fn test_setup_native() { + let mut context = get_context(); + + // Cannot instantiate with 0 due + let result = context.app.instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: ADMIN.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::zero(), + denom: UncheckedDenom::Native(DENOM.to_string()), }, - &[], + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ); + assert!(result.is_err()); + + // Can instantiate with some due + let result = context.app.instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: ADMIN.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::new(1000), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ); + assert!(result.is_ok()); + let dao_proposal_incentives_addr = result.unwrap(); + + // Ensure owner was set on init + let ownership: Ownership = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::Ownership {}, + ) + .unwrap(); + + assert_eq!(ownership.owner, Some(ADMIN.to_string())); + + // Ensure proposal incentives was set + let proposal_incentives: ProposalIncentives = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::ProposalIncentives { height: None }, ) .unwrap(); + assert_eq!( + proposal_incentives, + ProposalIncentives { + rewards_per_proposal: Uint128::new(1000), + denom: CheckedDenom::Native(DENOM.to_string()) + } + ); - // Get the core address from the instantiate event - let instantiate_event = &res.events[2]; - assert_eq!(instantiate_event.ty, "instantiate"); - let core_addr = instantiate_event.attributes[0].value.clone(); + // Cannot update rewards to zero + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::zero(), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &[], + ); + assert!(result.is_err()); - // Check that admin of core address is itself - let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); - assert_eq!(contract_info.admin, Some(core_addr)) + // Cannot update unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::one(), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &[], + ); + assert!(result.is_err()); + + // Can update rewards + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::one(), + denom: UncheckedDenom::Cw20(context.cw20_addr.to_string()), + }, + }, + &[], + ); + assert!(result.is_ok()); + + // Ensure proposal incentives was updated + let proposal_incentives: ProposalIncentives = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::ProposalIncentives { height: None }, + ) + .unwrap(); + assert_eq!( + proposal_incentives, + ProposalIncentives { + rewards_per_proposal: Uint128::one(), + denom: CheckedDenom::Cw20(context.cw20_addr.clone()), + } + ); } #[test] -pub fn test_set_admin_mock() { - let mut deps = mock_dependencies(); - // Instantiate factory contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info("creator", &[]); - let env = mock_env(); - instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); - let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; - let reply_msg: Reply = Reply { - id: INSTANTIATE_CONTRACT_REPLY_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: (Some(Binary(bytes))), - }), - }; - - let res = reply(deps.as_mut(), env, reply_msg).unwrap(); - assert_eq!(res.attributes.len(), 1); +pub fn test_hook() { + let mut context = get_context(); + + // Create the proposal incentives contract + let dao_proposal_incentives_addr = context + .app + .instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::new(1000), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ) + .unwrap(); + context.app.update_block(|x| x.height += 10); + + // Execute fails - unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::ProposalHook( + dao_hooks::proposal::ProposalHookMsg::ProposalStatusChanged { + id: 1u64, + old_status: "open".to_string(), + new_status: "passed".to_string(), + }, + ), + &[], + ); + assert!(result.is_err()); + + // Fund the incentives contract for 1 reward + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + + // Fund the incentives contract with cw20 as well to show cw20 support + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + context.cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::Send { + contract: dao_proposal_incentives_addr.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }, + &[], + ); + assert!(result.is_ok()); + + // Propose adding a hook + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add proposal hook".to_string(), + description: "Adding a proposal hook to test the dao_proposal_incentives contract" + .to_string(), + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { + address: dao_proposal_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + })], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Vote and execute the proposal to add the proposal hook + vote_yes_on_proposal(&mut context, 1u64).unwrap(); + execute_proposal(&mut context, 1u64); + + // Query for the newly-established hook + let result: cw_hooks::HooksResponse = context + .app + .wrap() + .query_wasm_smart( + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::QueryMsg::ProposalHooks {}, + ) + .unwrap(); + assert!(result + .hooks + .contains(&dao_proposal_incentives_addr.to_string())); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Assert that the proposal hook's execution has sent funds to proposer + let result = vote_yes_on_proposal(&mut context, 2u64); + assert!(result.is_ok()); + let balance = context.app.wrap().query_balance(ADDR1, DENOM).unwrap(); assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::UpdateAdmin { - contract_addr: "contract2".to_string(), - admin: "contract2".to_string() - }) - ) + balance, + Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000) + } + ); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Assert that the proposal hook's failure still allows completion + // The hook is attempting to send funds when it has run out of funds + let result = vote_yes_on_proposal(&mut context, 3u64); + assert!(result.is_ok()); + assert!(result.unwrap().events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_proposal_hook" + && y.value == format!("{0}:0", dao_proposal_incentives_addr)))); } #[test] pub fn test_migrate_update_version() { let mut deps = mock_dependencies(); cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg::FromCompatible {}).unwrap(); let version = cw2::get_contract_version(&deps.storage).unwrap(); assert_eq!(version.version, CONTRACT_VERSION); assert_eq!(version.contract, CONTRACT_NAME); diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index d80c6b322..a64900db1 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -32,3 +32,4 @@ cosmwasm-schema = { workspace = true } cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } +cw-hooks = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 28ff99777..8ee17afc0 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; use cw_utils::must_pay; use dao_hooks::vote::VoteHookMsg; diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index 3bee180ee..8b1378917 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -1,168 +1 @@ -use std::vec; -use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, -}; - -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; -use dao_interface::state::{Admin, ModuleInstantiateInfo}; - -use crate::{ - contract::instantiate, - contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, - msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, -}; - -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} - -#[test] -pub fn test_set_admin() { - let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); - let cw20_instantiate = cw20_base::msg::InstantiateMsg { - name: "DAO".to_string(), - symbol: "DAO".to_string(), - decimals: 6, - initial_balances: vec![], - mint: None, - marketing: None, - }; - - let instantiate = InstantiateMsg {}; - let factory_addr = app - .instantiate_contract( - code_id, - Addr::unchecked("CREATOR"), - &instantiate, - &[], - "cw-admin-factory", - None, - ) - .unwrap(); - - // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); - let instantiate_core = dao_interface::msg::InstantiateMsg { - dao_uri: None, - admin: None, - name: "DAO DAO".to_string(), - description: "A DAO that builds DAOs.".to_string(), - image_url: None, - automatically_add_cw20s: true, - automatically_add_cw721s: true, - voting_module_instantiate_info: ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "voting module".to_string(), - }, - proposal_modules_instantiate_info: vec![ - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module".to_string(), - }, - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module 2".to_string(), - }, - ], - initial_items: None, - }; - - let res: AppResponse = app - .execute_contract( - Addr::unchecked("CREATOR"), - factory_addr, - &ExecuteMsg::InstantiateContractWithSelfAdmin { - instantiate_msg: to_json_binary(&instantiate_core).unwrap(), - code_id: cw_core_code_id, - label: "my contract".to_string(), - }, - &[], - ) - .unwrap(); - - // Get the core address from the instantiate event - let instantiate_event = &res.events[2]; - assert_eq!(instantiate_event.ty, "instantiate"); - let core_addr = instantiate_event.attributes[0].value.clone(); - - // Check that admin of core address is itself - let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); - assert_eq!(contract_info.admin, Some(core_addr)) -} - -#[test] -pub fn test_set_admin_mock() { - let mut deps = mock_dependencies(); - // Instantiate factory contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info("creator", &[]); - let env = mock_env(); - instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); - let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; - let reply_msg: Reply = Reply { - id: INSTANTIATE_CONTRACT_REPLY_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: (Some(Binary(bytes))), - }), - }; - - let res = reply(deps.as_mut(), env, reply_msg).unwrap(); - assert_eq!(res.attributes.len(), 1); - assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::UpdateAdmin { - contract_addr: "contract2".to_string(), - admin: "contract2".to_string() - }) - ) -} - -#[test] -pub fn test_migrate_update_version() { - let mut deps = mock_dependencies(); - cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); - let version = cw2::get_contract_version(&deps.storage).unwrap(); - assert_eq!(version.version, CONTRACT_VERSION); - assert_eq!(version.contract, CONTRACT_NAME); -} diff --git a/contracts/proposal/dao-proposal-condorcet/src/contract.rs b/contracts/proposal/dao-proposal-condorcet/src/contract.rs index f6b5406f3..1f657b204 100644 --- a/contracts/proposal/dao-proposal-condorcet/src/contract.rs +++ b/contracts/proposal/dao-proposal-condorcet/src/contract.rs @@ -260,6 +260,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Info {} => to_json_binary(&dao_interface::voting::InfoResponse { info: cw2::get_contract_version(deps.storage)?, }), + QueryMsg::GenericProposalInfo { proposal_id: _ } => unimplemented!(), } } diff --git a/contracts/proposal/dao-proposal-multiple/src/contract.rs b/contracts/proposal/dao-proposal-multiple/src/contract.rs index 09d304964..2788e3f2b 100644 --- a/contracts/proposal/dao-proposal-multiple/src/contract.rs +++ b/contracts/proposal/dao-proposal-multiple/src/contract.rs @@ -842,9 +842,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalHooks {} => to_json_binary(&PROPOSAL_HOOKS.query_hooks(deps)?), QueryMsg::VoteHooks {} => to_json_binary(&VOTE_HOOKS.query_hooks(deps)?), QueryMsg::Dao {} => query_dao(deps), + QueryMsg::GenericProposalInfo { proposal_id } => { + query_generic_proposal_info(deps, proposal_id) + } } } +pub fn query_generic_proposal_info(deps: Deps, id: u64) -> StdResult { + to_json_binary(&PROPOSALS.load(deps.storage, id)?.into_generic()) +} + pub fn query_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; to_json_binary(&config) diff --git a/contracts/proposal/dao-proposal-multiple/src/proposal.rs b/contracts/proposal/dao-proposal-multiple/src/proposal.rs index 454a60762..5d760b477 100644 --- a/contracts/proposal/dao-proposal-multiple/src/proposal.rs +++ b/contracts/proposal/dao-proposal-multiple/src/proposal.rs @@ -3,6 +3,7 @@ use std::ops::Add; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, StdError, StdResult, Uint128}; use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; use dao_voting::{ multiple_choice::{ CheckedMultipleChoiceOption, MultipleChoiceOptionType, MultipleChoiceVotes, VotingStrategy, @@ -283,6 +284,13 @@ impl MultipleChoiceProposal { } Ok(false) } + + pub fn into_generic(self) -> GenericProposalInfo { + GenericProposalInfo { + proposer: self.proposer, + start_height: self.start_height, + } + } } #[cfg(test)] diff --git a/contracts/proposal/dao-proposal-single/Cargo.toml b/contracts/proposal/dao-proposal-single/Cargo.toml index 06170dd00..6bc126fa9 100644 --- a/contracts/proposal/dao-proposal-single/Cargo.toml +++ b/contracts/proposal/dao-proposal-single/Cargo.toml @@ -54,3 +54,4 @@ cw721-base = { workspace = true } cw4 = { workspace = true } cw4-group = { workspace = true } cw-core-v1 = { workspace = true, features = ["library"] } +dao-proposal-incentives = { workspace = true } diff --git a/contracts/proposal/dao-proposal-single/src/contract.rs b/contracts/proposal/dao-proposal-single/src/contract.rs index 711a2f481..3965f2b40 100644 --- a/contracts/proposal/dao-proposal-single/src/contract.rs +++ b/contracts/proposal/dao-proposal-single/src/contract.rs @@ -822,9 +822,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalCreationPolicy {} => query_creation_policy(deps), QueryMsg::ProposalHooks {} => to_json_binary(&PROPOSAL_HOOKS.query_hooks(deps)?), QueryMsg::VoteHooks {} => to_json_binary(&VOTE_HOOKS.query_hooks(deps)?), + QueryMsg::GenericProposalInfo { proposal_id } => { + query_generic_proposal_info(deps, proposal_id) + } } } +pub fn query_generic_proposal_info(deps: Deps, id: u64) -> StdResult { + to_json_binary(&PROPOSALS.load(deps.storage, id)?.into_generic()) +} + pub fn query_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; to_json_binary(&config) diff --git a/contracts/proposal/dao-proposal-single/src/proposal.rs b/contracts/proposal/dao-proposal-single/src/proposal.rs index a597f3754..0cef6eec3 100644 --- a/contracts/proposal/dao-proposal-single/src/proposal.rs +++ b/contracts/proposal/dao-proposal-single/src/proposal.rs @@ -5,6 +5,7 @@ use crate::state::PROPOSAL_COUNT; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; use dao_voting::status::Status; use dao_voting::threshold::{PercentageThreshold, Threshold}; use dao_voting::veto::VetoConfig; @@ -270,6 +271,13 @@ impl SingleChoiceProposal { } } } + + pub fn into_generic(self) -> GenericProposalInfo { + GenericProposalInfo { + proposer: self.proposer, + start_height: self.start_height, + } + } } #[cfg(test)] diff --git a/packages/dao-dao-macros/src/lib.rs b/packages/dao-dao-macros/src/lib.rs index 48611fddf..8b45a9a6e 100644 --- a/packages/dao-dao-macros/src/lib.rs +++ b/packages/dao-dao-macros/src/lib.rs @@ -392,6 +392,9 @@ pub fn proposal_module_query(metadata: TokenStream, input: TokenStream) -> Token /// next proposal created. #[returns(::std::primitive::u64)] NextProposalId {}, + /// Returns generic proposal information + #[returns(dao_interface::proposal::GenericProposalInfo)] + GenericProposalInfo { proposal_id: ::std::primitive::u64 }, } } .into(), diff --git a/packages/dao-dao-macros/tests/govmod.rs b/packages/dao-dao-macros/tests/govmod.rs index f69d281cb..5c437de73 100644 --- a/packages/dao-dao-macros/tests/govmod.rs +++ b/packages/dao-dao-macros/tests/govmod.rs @@ -24,5 +24,6 @@ fn proposal_module_query_derive() { Test::Foo | Test::Bar(_) | Test::Baz { .. } | Test::Dao {} => "yay", Test::Info {} => "yay", Test::NextProposalId {} => "yay", + Test::GenericProposalInfo { proposal_id: _ } => "yay", }; } diff --git a/packages/dao-hooks/src/proposal.rs b/packages/dao-hooks/src/proposal.rs index c98cfdc45..20f915d4a 100644 --- a/packages/dao-hooks/src/proposal.rs +++ b/packages/dao-hooks/src/proposal.rs @@ -8,7 +8,7 @@ use dao_voting::{ }; /// An enum representing proposal hook messages. -/// Either a new propsoal hook, fired when a new proposal is created, +/// Either a new proposal hook, fired when a new proposal is created, /// or a proposal status hook, fired when a proposal changes status. #[cw_serde] pub enum ProposalHookMsg { diff --git a/packages/dao-interface/src/msg.rs b/packages/dao-interface/src/msg.rs index 797865c2e..8280b51a6 100644 --- a/packages/dao-interface/src/msg.rs +++ b/packages/dao-interface/src/msg.rs @@ -191,6 +191,9 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + // Gets a proposal module + #[returns(crate::state::ProposalModule)] + ProposalModule { address: String }, /// Gets the active proposal modules associated with the /// contract. #[returns(Vec)] diff --git a/packages/dao-interface/src/proposal.rs b/packages/dao-interface/src/proposal.rs index 77076d5c2..f71868986 100644 --- a/packages/dao-interface/src/proposal.rs +++ b/packages/dao-interface/src/proposal.rs @@ -1,4 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Addr; use cw2::ContractVersion; #[cw_serde] @@ -6,6 +7,12 @@ pub struct InfoResponse { pub info: ContractVersion, } +#[cw_serde] +pub struct GenericProposalInfo { + pub proposer: Addr, + pub start_height: u64, +} + #[cw_serde] #[derive(QueryResponses)] pub enum Query { @@ -19,6 +26,9 @@ pub enum Query { /// next proposal created. #[returns(::std::primitive::u64)] NextProposalId {}, + /// Returns generic proposal information + #[returns(GenericProposalInfo)] + GenericProposalInfo { proposal_id: ::std::primitive::u64 }, } mod tests { @@ -34,6 +44,7 @@ mod tests { Query::Dao {} => (), Query::Info {} => (), Query::NextProposalId {} => (), + Query::GenericProposalInfo { proposal_id: _ } => (), } } } diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index 51d0685b4..73df2521b 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -58,3 +58,4 @@ dao-voting-cw721-roles = { workspace = true } dao-voting-token-staked = { workspace = true } voting-v1 = { workspace = true } stake-cw20-v03 = { workspace = true } +dao-proposal-incentives = { workspace = true } \ No newline at end of file diff --git a/packages/dao-testing/src/contracts.rs b/packages/dao-testing/src/contracts.rs index a0418a48f..8ab5ab9ee 100644 --- a/packages/dao-testing/src/contracts.rs +++ b/packages/dao-testing/src/contracts.rs @@ -206,3 +206,13 @@ pub fn dao_test_custom_factory() -> Box> { .with_reply(dao_test_custom_factory::contract::reply); Box::new(contract) } + +pub fn dao_proposal_incentives_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_incentives::contract::execute, + dao_proposal_incentives::contract::instantiate, + dao_proposal_incentives::contract::query, + ); + + Box::new(contract) +} From 834e16ee5783789fb3850f361a535834c58f50d4 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 15:08:40 -0600 Subject: [PATCH 09/47] Fix clippy errors --- .../dao-proposal-incentives/src/execute.rs | 54 +++++++++---------- .../dao-voting-incentives/src/contract.rs | 16 +++--- .../external/dao-voting-incentives/src/lib.rs | 3 -- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs index b7d30dfe4..bafeac650 100644 --- a/contracts/external/dao-proposal-incentives/src/execute.rs +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -29,36 +29,34 @@ pub fn proposal_hook( )?; // Check prop status and type of hook - match msg { - ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } => { - // If prop status is success, add message to pay out rewards - // Otherwise, do nothing - if new_status == Status::Passed.to_string() { - // Query for the proposal - let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( - info.sender, - &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, - )?; - - // Load proposal incentives config - let proposal_incentives = PROPOSAL_INCENTIVES - .may_load_at_height(deps.storage, proposal_info.start_height)?; - - // Append the message if found - if let Some(proposal_incentives) = proposal_incentives { - msgs.push(proposal_incentives.denom.get_transfer_to_message( - &proposal_info.proposer, - proposal_incentives.rewards_per_proposal, - )?); - attrs = proposal_incentives.into_attributes(); - attrs.push(Attribute { - key: "proposer".to_string(), - value: proposal_info.proposer.to_string(), - }); - } + + if let ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } = msg { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Query for the proposal + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender, + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, + )?; + + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, proposal_info.start_height)?; + + // Append the message if found + if let Some(proposal_incentives) = proposal_incentives { + msgs.push(proposal_incentives.denom.get_transfer_to_message( + &proposal_info.proposer, + proposal_incentives.rewards_per_proposal, + )?); + attrs = proposal_incentives.into_attributes(); + attrs.push(Attribute { + key: "proposer".to_string(), + value: proposal_info.proposer.to_string(), + }); } } - _ => {} } } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 8ee17afc0..f68cbde11 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -57,8 +57,8 @@ pub fn execute( // TODO how to claim for many epochs efficiently? pub fn execute_claim( deps: DepsMut, - env: Env, - info: MessageInfo, + _env: Env, + _info: MessageInfo, ) -> Result { // Check epoch should advance @@ -69,7 +69,7 @@ pub fn execute_claim( // Load prop count for epoch // Load voting incentives config - let voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; + let _voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; // Need total vote count for epoch // Rewards = (user vote count / prop count) / total_vote_count * voting incentives @@ -82,10 +82,10 @@ pub fn execute_claim( // TODO support cw20 tokens // TODO make sure config can't lock DAO pub fn execute_vote_hook( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: VoteHookMsg, + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: VoteHookMsg, ) -> Result { // Check epoch should advance @@ -102,7 +102,7 @@ pub fn execute_vote_hook( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address } => unimplemented!(), + QueryMsg::Rewards { address: _ } => unimplemented!(), QueryMsg::Config {} => unimplemented!(), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index d1800adbc..595daabe0 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -5,7 +5,4 @@ mod error; pub mod msg; pub mod state; -#[cfg(test)] -mod tests; - pub use crate::error::ContractError; From 34c747437bc6f0ed76c5145e4bd85c1922d333a8 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 15:18:49 -0600 Subject: [PATCH 10/47] More clippy --- .../dao-proposal-incentives/src/tests.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 340952ab1..2d58c275c 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -142,7 +142,7 @@ fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> AnyResult Date: Wed, 31 Jan 2024 21:25:39 -0600 Subject: [PATCH 11/47] Schema + clippy fix --- .../schema/cw-admin-factory.json | 69 -- .../schema/dao-proposal-incentives.json | 623 ++++++++++++++++++ .../dao-proposal-incentives/src/tests.rs | 2 +- .../external/dao-voting-incentives/README.md | 4 +- .../dao-voting-incentives/src/tests.rs | 1 - 5 files changed, 626 insertions(+), 73 deletions(-) delete mode 100644 contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json delete mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json deleted file mode 100644 index f1a1e1254..000000000 --- a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "contract_name": "cw-admin-factory", - "contract_version": "2.4.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", - "type": "object", - "required": [ - "instantiate_contract_with_self_admin" - ], - "properties": { - "instantiate_contract_with_self_admin": { - "type": "object", - "required": [ - "code_id", - "instantiate_msg", - "label" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - }, - "label": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "type": "string", - "enum": [] - }, - "migrate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MigrateMsg", - "type": "object", - "additionalProperties": false - }, - "sudo": null, - "responses": {} -} diff --git a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json new file mode 100644 index 000000000..2d02b5883 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json @@ -0,0 +1,623 @@ +{ + "contract_name": "dao-proposal-incentives", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "owner", + "proposal_incentives" + ], + "properties": { + "owner": { + "description": "The contract's owner using cw-ownable", + "type": "string" + }, + "proposal_incentives": { + "description": "Rewards to pay out for successful proposals.", + "allOf": [ + { + "$ref": "#/definitions/ProposalIncentivesUnchecked" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "ProposalIncentivesUnchecked": { + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/UncheckedDenom" + }, + "rewards_per_proposal": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Fires when a new proposal status has changed.", + "type": "object", + "required": [ + "proposal_hook" + ], + "properties": { + "proposal_hook": { + "$ref": "#/definitions/ProposalHookMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_proposal_incentives" + ], + "properties": { + "update_proposal_incentives": { + "type": "object", + "required": [ + "proposal_incentives" + ], + "properties": { + "proposal_incentives": { + "$ref": "#/definitions/ProposalIncentivesUnchecked" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ProposalHookMsg": { + "description": "An enum representing proposal hook messages. Either a new proposal hook, fired when a new proposal is created, or a proposal status hook, fired when a proposal changes status.", + "oneOf": [ + { + "type": "object", + "required": [ + "new_proposal" + ], + "properties": { + "new_proposal": { + "type": "object", + "required": [ + "id", + "proposer" + ], + "properties": { + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "proposer": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "proposal_status_changed" + ], + "properties": { + "proposal_status_changed": { + "type": "object", + "required": [ + "id", + "new_status", + "old_status" + ], + "properties": { + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "new_status": { + "type": "string" + }, + "old_status": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ProposalIncentivesUnchecked": { + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/UncheckedDenom" + }, + "rewards_per_proposal": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the proposal incentives", + "type": "object", + "required": [ + "proposal_incentives" + ], + "properties": { + "proposal_incentives": { + "type": "object", + "properties": { + "height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the contract's ownership information", + "type": "object", + "required": [ + "ownership" + ], + "properties": { + "ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_compatible" + ], + "properties": { + "from_compatible": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "sudo": null, + "responses": { + "ownership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Ownership_for_String", + "description": "The contract's ownership info", + "type": "object", + "properties": { + "owner": { + "description": "The contract's current owner. `None` if the ownership has been renounced.", + "type": [ + "string", + "null" + ] + }, + "pending_expiry": { + "description": "The deadline for the pending owner to accept the ownership. `None` if there isn't a pending ownership transfer, or if a transfer exists and it doesn't have a deadline.", + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "pending_owner": { + "description": "The account who has been proposed to take over the ownership. `None` if there isn't a pending ownership transfer.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "proposal_incentives": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalIncentives", + "description": "Incentives for passing successful proposals", + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/CheckedDenom" + }, + "rewards_per_proposal": { + "description": "The rewards to pay out per successful proposal.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 2d58c275c..6afc2dedf 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -331,7 +331,7 @@ pub fn test_hook() { .send_tokens( Addr::unchecked(ADMIN), dao_proposal_incentives_addr.clone(), - &vec![Coin { + &[Coin { denom: DENOM.to_string(), amount: Uint128::new(1000), }], diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index f41943baf..df486cb0c 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -9,9 +9,9 @@ When creating this contract, the DAO specifies an `epoch_duration` and an amount At the end of the epoch, rewards are payable as follows: -``` +`` rewards = (user vote count / prop count) / total_vote_count * voting incentives -``` +`` If no proposals happen during an epoch, no rewards are paid out. diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs deleted file mode 100644 index 8b1378917..000000000 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ /dev/null @@ -1 +0,0 @@ - From ed344a4b55a377bc1207b04c64d0f2248e245c01 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 12:32:39 -0600 Subject: [PATCH 12/47] Progress on voting incentives Need to add tests --- Cargo.lock | 3 + .../dao-proposal-incentives/src/error.rs | 3 + .../dao-proposal-incentives/src/execute.rs | 14 +- .../external/dao-voting-incentives/Cargo.toml | 5 +- .../schema/cw-admin-factory.json | 69 -- .../schema/dao-voting-incentives.json | 695 ++++++++++++++++++ .../dao-voting-incentives/src/contract.rs | 113 ++- .../dao-voting-incentives/src/error.rs | 33 +- .../dao-voting-incentives/src/execute.rs | 226 ++++++ .../external/dao-voting-incentives/src/lib.rs | 2 + .../external/dao-voting-incentives/src/msg.rs | 48 +- .../dao-voting-incentives/src/query.rs | 23 + .../dao-voting-incentives/src/state.rs | 95 ++- 13 files changed, 1143 insertions(+), 186 deletions(-) delete mode 100644 contracts/external/dao-voting-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json create mode 100644 contracts/external/dao-voting-incentives/src/execute.rs create mode 100644 contracts/external/dao-voting-incentives/src/query.rs diff --git a/Cargo.lock b/Cargo.lock index 7a027be43..efef129ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2161,11 +2161,14 @@ version = "2.4.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-denom", "cw-hooks", "cw-multi-test", + "cw-ownable", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", + "cw20 1.1.2", "cw20-base 1.1.2", "dao-dao-core", "dao-hooks", diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index ee3ba8822..57a1a362c 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -29,4 +29,7 @@ pub enum ContractError { #[error("No reward per proposal given")] NoRewardPerProposal {}, + + #[error("Proposal module is inactive")] + ProposalModuleIsInactive {}, } diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs index bafeac650..95267ff27 100644 --- a/contracts/external/dao-proposal-incentives/src/execute.rs +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -2,7 +2,10 @@ use cosmwasm_std::{Attribute, CosmosMsg, DepsMut, Env, MessageInfo, Response}; use cw20::Cw20ReceiveMsg; use cw_ownable::{assert_owner, get_ownership}; use dao_hooks::proposal::ProposalHookMsg; -use dao_interface::{proposal::GenericProposalInfo, state::ProposalModule}; +use dao_interface::{ + proposal::GenericProposalInfo, + state::{ProposalModule, ProposalModuleStatus}, +}; use dao_voting::status::Status; use crate::{msg::ProposalIncentivesUnchecked, state::PROPOSAL_INCENTIVES, ContractError}; @@ -21,15 +24,19 @@ pub fn proposal_hook( if let Some(owner) = ownership.owner { // Validate the message is coming from a proposal module of the owner (DAO) - deps.querier.query_wasm_smart::( + let proposal_module = deps.querier.query_wasm_smart::( owner, &dao_interface::msg::QueryMsg::ProposalModule { address: info.sender.to_string(), }, )?; - // Check prop status and type of hook + // If the proposal module is disabled, then return error + if proposal_module.status == ProposalModuleStatus::Disabled { + return Err(ContractError::ProposalModuleIsInactive {}); + } + // Check prop status and type of hook if let ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } = msg { // If prop status is success, add message to pay out rewards // Otherwise, do nothing @@ -104,6 +111,7 @@ pub fn receive_cw20( info: MessageInfo, _cw20_receive_msg: Cw20ReceiveMsg, ) -> Result { + // We do not check cw20, because the expected fund can change over time Ok(Response::new() .add_attribute("action", "receive_cw20") .add_attribute("cw20", info.sender)) diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index a64900db1..fbeccc8c0 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-voting-incentives" -authors = ["Jake Hartnell "] +authors = ["Jake Hartnell ", "ismellike"] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } @@ -26,6 +26,9 @@ dao-interface = { workspace = true } dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } +cw-denom = { workspace = true } +cw-ownable = { workspace = true } +cw20 = { workspace = true } [dev-dependencies] cosmwasm-schema = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json deleted file mode 100644 index f1a1e1254..000000000 --- a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "contract_name": "cw-admin-factory", - "contract_version": "2.4.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", - "type": "object", - "required": [ - "instantiate_contract_with_self_admin" - ], - "properties": { - "instantiate_contract_with_self_admin": { - "type": "object", - "required": [ - "code_id", - "instantiate_msg", - "label" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - }, - "label": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "type": "string", - "enum": [] - }, - "migrate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MigrateMsg", - "type": "object", - "additionalProperties": false - }, - "sudo": null, - "responses": {} -} diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json new file mode 100644 index 000000000..0bfbb8c10 --- /dev/null +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -0,0 +1,695 @@ +{ + "contract_name": "dao-voting-incentives", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "denom", + "expiration", + "owner" + ], + "properties": { + "denom": { + "description": "The denom to distribute", + "allOf": [ + { + "$ref": "#/definitions/UncheckedDenom" + } + ] + }, + "expiration": { + "description": "The expiration of the voting incentives", + "allOf": [ + { + "$ref": "#/definitions/Expiration" + } + ] + }, + "owner": { + "description": "The contract's owner using cw-ownable", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Fires when a new vote is cast.", + "type": "object", + "required": [ + "vote_hook" + ], + "properties": { + "vote_hook": { + "$ref": "#/definitions/VoteHookMsg" + } + }, + "additionalProperties": false + }, + { + "description": "Claim rewards", + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Expire the voting incentives period", + "type": "object", + "required": [ + "expire" + ], + "properties": { + "expire": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteHookMsg": { + "description": "An enum representing vote hooks, fired when new votes are cast.", + "oneOf": [ + { + "type": "object", + "required": [ + "new_vote" + ], + "properties": { + "new_vote": { + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "type": "string" + }, + "voter": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the config", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the claimable rewards for the given address.", + "type": "object", + "required": [ + "rewards" + ], + "properties": { + "rewards": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the expected rewards for the given address", + "type": "object", + "required": [ + "expected_rewards" + ], + "properties": { + "expected_rewards": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the contract's ownership information", + "type": "object", + "required": [ + "ownership" + ], + "properties": { + "ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_compatible" + ], + "properties": { + "from_compatible": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "sudo": null, + "responses": { + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "Top level config type for core module.", + "type": "object", + "required": [ + "automatically_add_cw20s", + "automatically_add_cw721s", + "description", + "name" + ], + "properties": { + "automatically_add_cw20s": { + "description": "If true the contract will automatically add received cw20 tokens to its treasury.", + "type": "boolean" + }, + "automatically_add_cw721s": { + "description": "If true the contract will automatically add received cw721 tokens to its treasury.", + "type": "boolean" + }, + "dao_uri": { + "description": "The URI for the DAO as defined by the DAOstar standard ", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "A description of the contract.", + "type": "string" + }, + "image_url": { + "description": "An optional image URL for displaying alongside the contract.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "The name of the contract.", + "type": "string" + } + }, + "additionalProperties": false + }, + "expected_rewards": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardResponse", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "$ref": "#/definitions/CheckedDenom" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "ownership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Ownership_for_String", + "description": "The contract's ownership info", + "type": "object", + "properties": { + "owner": { + "description": "The contract's current owner. `None` if the ownership has been renounced.", + "type": [ + "string", + "null" + ] + }, + "pending_expiry": { + "description": "The deadline for the pending owner to accept the ownership. `None` if there isn't a pending ownership transfer, or if a transfer exists and it doesn't have a deadline.", + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "pending_owner": { + "description": "The account who has been proposed to take over the ownership. `None` if there isn't a pending ownership transfer.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "rewards": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardResponse", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "$ref": "#/definitions/CheckedDenom" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index f68cbde11..32ca6e86b 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,13 +1,15 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{ + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, +}; use cw2::set_contract_version; -use cw_utils::must_pay; -use dao_hooks::vote::VoteHookMsg; +use cw_ownable::get_ownership; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{DAO, VOTING_INCENTIVES}; +use crate::state::{Config, CONFIG}; +use crate::{execute, query}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -15,30 +17,41 @@ pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save DAO, assumes the sender is the DAO - DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + // Save ownership + let ownership = cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; - // Save voting incentives config - VOTING_INCENTIVES.save(deps.storage, &msg.voting_incentives)?; + // Validate denom + let denom = msg.denom.into_checked(deps.as_ref())?; + + // Validate expiration + if msg.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } - // Check initial deposit is enough to pay out rewards for at least one epoch - let amount = must_pay(&info, &msg.voting_incentives.rewards_per_epoch.denom)?; - if amount < msg.voting_incentives.rewards_per_epoch.amount { - return Err(ContractError::InsufficientInitialDeposit { - expected: msg.voting_incentives.rewards_per_epoch.amount, - actual: amount, - }); - }; + // Save voting incentives config + CONFIG.save( + deps.storage, + &Config { + start_height: env.block.height, + expiration: msg.expiration, + denom: denom.clone(), + total_votes: Uint128::zero(), + expiration_balance: None, + }, + )?; Ok(Response::new() .add_attribute("method", "instantiate") - .add_attribute("creator", info.sender)) + .add_attribute("creator", info.sender) + .add_attribute("expiration", msg.expiration.to_string()) + .add_attribute("denom", denom.to_string()) + .add_attributes(ownership.into_attributes())) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -49,61 +62,25 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Claim {} => execute_claim(deps, env, info), - ExecuteMsg::VoteHook(msg) => execute_vote_hook(deps, env, info, msg), + ExecuteMsg::Claim {} => execute::claim(deps, env, info), + ExecuteMsg::VoteHook(msg) => execute::vote_hook(deps, env, info, msg), + ExecuteMsg::Expire {} => execute::expire(deps, env, info), + ExecuteMsg::UpdateOwnership(action) => execute::update_ownership(deps, env, info, action), + ExecuteMsg::Receive(cw20_receive_msg) => { + execute::receive_cw20(deps, env, info, cw20_receive_msg) + } } } -// TODO how to claim for many epochs efficiently? -pub fn execute_claim( - deps: DepsMut, - _env: Env, - _info: MessageInfo, -) -> Result { - // Check epoch should advance - - // Save last claimed epoch - - // Load user vote count for epoch? - - // Load prop count for epoch - - // Load voting incentives config - let _voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; - - // Need total vote count for epoch - // Rewards = (user vote count / prop count) / total_vote_count * voting incentives - - // Pay out rewards - - Ok(Response::default().add_attribute("action", "claim")) -} - -// TODO support cw20 tokens -// TODO make sure config can't lock DAO -pub fn execute_vote_hook( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: VoteHookMsg, -) -> Result { - // Check epoch should advance - - // TODO need some state to handle this - // Check that the vote is not a changed vote (i.e. the user has already voted - // on the prop). - - // Save (user, epoch), vote count - // Update (epoch, prop count) - - Ok(Response::default().add_attribute("action", "vote_hook")) -} - #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address: _ } => unimplemented!(), - QueryMsg::Config {} => unimplemented!(), + QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, address)?), + QueryMsg::ExpectedRewards { address } => { + to_json_binary(&query::expected_rewards(deps, env, address)?) + } + QueryMsg::Config {} => to_json_binary(&query::config(deps)?), + QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), } } diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 2b1469dcb..15b5024ad 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -1,5 +1,7 @@ -use cosmwasm_std::{StdError, Uint128}; -use cw_utils::{ParseReplyError, PaymentError}; +use cosmwasm_std::{CheckedMultiplyFractionError, OverflowError, StdError}; +use cw_denom::{CheckedDenom, DenomError}; +use cw_ownable::OwnershipError; +use cw_utils::Expiration; use thiserror::Error; #[derive(Error, Debug)] @@ -8,17 +10,32 @@ pub enum ContractError { Std(#[from] StdError), #[error("{0}")] - ParseReplyError(#[from] ParseReplyError), + DenomError(#[from] DenomError), #[error("{0}")] - PaymentError(#[from] PaymentError), + OwnershipError(#[from] OwnershipError), - #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] - InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + #[error("{0}")] + CheckedMultiplyFractionError(#[from] CheckedMultiplyFractionError), + + #[error("{0}")] + OverflowError(#[from] OverflowError), #[error("Unauthorized")] Unauthorized {}, - #[error("An unknown reply ID was received.")] - UnknownReplyID {}, + #[error("NotExpired")] + NotExpired { expiration: Expiration }, + + #[error("AlreadyExpired")] + AlreadyExpired {}, + + #[error("Proposal module is inactive")] + ProposalModuleIsInactive {}, + + #[error("UnexpectedFunds")] + UnexpectedFunds { + expected: CheckedDenom, + received: CheckedDenom, + }, } diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs new file mode 100644 index 000000000..df5a75205 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -0,0 +1,226 @@ +use cosmwasm_std::{Attribute, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; +use cw20::Cw20ReceiveMsg; +use cw_denom::CheckedDenom; +use cw_ownable::get_ownership; +use dao_hooks::vote::VoteHookMsg; +use dao_interface::{ + proposal::GenericProposalInfo, + state::{ProposalModule, ProposalModuleStatus}, +}; + +use crate::{ + state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_VOTE_COUNT}, + ContractError, +}; + +pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + // Get reward information + let reward = reward(deps.as_ref(), &info.sender)?; + + // If the user has rewards, then we should generate a message + let mut msgs = vec![]; + if !reward.amount.is_zero() { + msgs.push( + reward + .denom + .get_transfer_to_message(&info.sender, reward.amount)?, + ); + } + + // Clean state + USER_VOTE_COUNT.remove(deps.storage, &info.sender); + + Ok(Response::new() + .add_attribute("action", "claim") + .add_attribute("denom", reward.denom.to_string()) + .add_attribute("amount", reward.amount) + .add_messages(msgs)) +} + +pub fn update_ownership( + deps: DepsMut, + env: Env, + info: MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + + Ok(Response::new() + .add_attribute("action", "update_ownership") + .add_attributes(ownership.into_attributes())) +} + +pub fn vote_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: VoteHookMsg, +) -> Result { + let mut attrs: Vec = vec![]; + + // Get ownership + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + // Validate the message is coming from a proposal module of the owner (DAO) + let proposal_module = deps.querier.query_wasm_smart::( + owner, + &dao_interface::msg::QueryMsg::ProposalModule { + address: info.sender.to_string(), + }, + )?; + + // If the proposal module is disabled, then return error + if proposal_module.status == ProposalModuleStatus::Disabled { + return Err(ContractError::ProposalModuleIsInactive {}); + } + + // Check type of hook + match msg { + VoteHookMsg::NewVote { + proposal_id, voter, .. + } => { + if let Ok(voter) = deps.api.addr_validate(&voter) { + // Get config + let mut config = CONFIG.load(deps.storage)?; + + // Check if the voting incentives have expired + if config.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } + + // Get the proposal info + // If we have a value in the cache, then return the value + // If we don't have a value, then query for the value and set it in the cache + let proposal_info = if GENERIC_PROPOSAL_INFO + .has(deps.storage, (&info.sender, proposal_id)) + { + GENERIC_PROPOSAL_INFO.load(deps.storage, (&info.sender, proposal_id))? + } else { + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender.clone(), + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id }, + )?; + + GENERIC_PROPOSAL_INFO.save( + deps.storage, + (&info.sender, proposal_id), + &proposal_info, + )?; + + proposal_info + }; + + // Check if the vote came from a proposal at or after the start of the voting incentives + if proposal_info.start_height >= config.start_height { + // Increment counts + let user_votes = USER_VOTE_COUNT.update( + deps.storage, + &voter, + |x| -> StdResult { + Ok(x.unwrap_or_default().checked_add(Uint128::one())?) + }, + )?; + config.total_votes = config.total_votes.checked_add(Uint128::one())?; + CONFIG.save(deps.storage, &config)?; + + // Set attributes + attrs = vec![ + Attribute { + key: "total_votes".to_string(), + value: config.total_votes.to_string(), + }, + Attribute { + key: "user_votes".to_string(), + value: user_votes.to_string(), + }, + Attribute { + key: "user".to_string(), + value: voter.to_string(), + }, + ]; + } + } + } + } + } + + Ok(Response::new() + .add_attribute("action", "vote_hook") + .add_attributes(attrs)) +} + +pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result { + // Get the config + let mut config = CONFIG.load(deps.storage)?; + + // If already expired, then return an error + if config.expiration_balance.is_some() { + return Err(ContractError::AlreadyExpired {}); + } + + // Ensure the voting incentives period has passed expiration + if !config.expiration.is_expired(&env.block) { + return Err(ContractError::NotExpired { + expiration: config.expiration, + }); + } + + // Get the available balance to distribute + let balance = config + .denom + .query_balance(&deps.querier, &env.contract.address)?; + + // Save the balance + config.expiration_balance = Some(balance); + CONFIG.save(deps.storage, &config)?; + + // If no votes have occurred, then funds should be sent to the owner + let mut msgs = vec![]; + if USER_VOTE_COUNT.is_empty(deps.storage) { + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + msgs.push(config.denom.get_transfer_to_message(&owner, balance)?); + } + } + + // Clean state + GENERIC_PROPOSAL_INFO.clear(deps.storage); + + Ok(Response::new() + .add_attribute("action", "expire") + .add_attribute("balance", balance) + .add_messages(msgs)) +} + +pub fn receive_cw20( + deps: DepsMut, + _env: Env, + info: MessageInfo, + _cw20_receive_msg: Cw20ReceiveMsg, +) -> Result { + let config = CONFIG.load(deps.storage)?; + + // Do not accept unexpected cw20 + match &config.denom { + CheckedDenom::Native(_) => { + return Err(ContractError::UnexpectedFunds { + expected: config.denom, + received: CheckedDenom::Cw20(info.sender), + }) + } + CheckedDenom::Cw20(expected_cw20) => { + if expected_cw20 != info.sender { + return Err(ContractError::UnexpectedFunds { + expected: config.denom, + received: CheckedDenom::Cw20(info.sender), + }); + } + } + } + + Ok(Response::new() + .add_attribute("action", "receive_cw20") + .add_attribute("cw20", info.sender)) +} diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index 595daabe0..d2f25785c 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -2,7 +2,9 @@ pub mod contract; mod error; +pub mod execute; pub mod msg; +pub mod query; pub mod state; pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 5298657e6..1937ab74b 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,42 +1,56 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Uint128; +use cw20::Cw20ReceiveMsg; +use cw_denom::{CheckedDenom, UncheckedDenom}; +use cw_ownable::cw_ownable_query; +use cw_utils::Expiration; use dao_hooks::vote::VoteHookMsg; - -use crate::state::VotingIncentives; +use dao_interface::state::Config; #[cw_serde] pub struct InstantiateMsg { - /// DAO address - pub dao: String, - /// Rewards to pay out for voting. - pub voting_incentives: VotingIncentives, + /// The contract's owner using cw-ownable + pub owner: String, + /// The denom to distribute + pub denom: UncheckedDenom, + /// The expiration of the voting incentives + pub expiration: Expiration, } #[cw_serde] pub enum ExecuteMsg { /// Fires when a new vote is cast. VoteHook(VoteHookMsg), - /// Claim rewards. + /// Claim rewards Claim {}, + /// Expire the voting incentives period + Expire {}, + UpdateOwnership(cw_ownable::Action), + Receive(Cw20ReceiveMsg), } +#[cw_ownable_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - /// Returns the config. - #[returns(ConfigResponse)] + /// Returns the config + #[returns(Config)] Config {}, - /// Returns the rewards for the given address. - #[returns(cosmwasm_std::Uint128)] + /// Returns the claimable rewards for the given address. + #[returns(RewardResponse)] Rewards { address: String }, + /// Returns the expected rewards for the given address + #[returns(RewardResponse)] + ExpectedRewards { address: String }, } #[cw_serde] -pub struct ConfigResponse { - /// DAO address - pub dao: String, - /// Rewards to pay out for voting. - pub voting_incentives: VotingIncentives, +pub enum MigrateMsg { + FromCompatible {}, } #[cw_serde] -pub struct MigrateMsg {} +pub struct RewardResponse { + pub denom: CheckedDenom, + pub amount: Uint128, +} diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs new file mode 100644 index 000000000..96a6877ea --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -0,0 +1,23 @@ +use cosmwasm_std::{Deps, Env, StdError, StdResult}; + +use crate::{ + msg::RewardResponse, + state::{self, Config, CONFIG}, +}; + +pub fn rewards(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + state::reward(deps, &address).map_err(|x| StdError::GenericErr { msg: x.to_string() }) +} + +pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + state::expected_reward(deps, env, &address) + .map_err(|x| StdError::GenericErr { msg: x.to_string() }) +} + +pub fn config(deps: Deps) -> StdResult { + CONFIG.load(deps.storage) +} diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 730cd7fe3..571482860 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -1,33 +1,88 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin, Timestamp}; +use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Env, Uint128}; +use cw_denom::CheckedDenom; use cw_storage_plus::{Item, Map}; +use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; -/// The address of the DAO this contract serves -pub const DAO: Item = Item::new("dao"); +use crate::{msg::RewardResponse, ContractError}; /// Incentives for voting #[cw_serde] -pub struct VotingIncentives { - /// Epoch duration in seconds. Used for reward calculation. - pub epoch_duration: Timestamp, - /// The rewards to pay out per epoch. - pub rewards_per_epoch: Coin, +pub struct Config { + /// The start height of the voting incentives + pub start_height: u64, + /// The expiration of these voting incentives + pub expiration: Expiration, + /// The total rewards to be distributed + pub denom: CheckedDenom, + /// The total number of votes + pub total_votes: Uint128, + /// The balance at expiration + pub expiration_balance: Option, } -/// Holds VotingIncentives state -pub const VOTING_INCENTIVES: Item = Item::new("voting_incentives"); +/// A map of user address to vote count +pub const USER_VOTE_COUNT: Map<&Addr, Uint128> = Map::new("user_vote_count"); +/// The voting incentives config +pub const CONFIG: Item = Item::new("config"); +/// A cache of generic proposal information (proposal_module, proposal_id) +pub const GENERIC_PROPOSAL_INFO: Map<(&Addr, u64), GenericProposalInfo> = + Map::new("generic_proposal_info"); -/// The current epoch -pub const EPOCH: Item = Item::new("epoch"); +/// A method to load reward information +pub fn reward(deps: Deps, addr: &Addr) -> Result { + let config = CONFIG.load(deps.storage)?; -/// A map of addresses to their last claimed epoch -pub const LAST_CLAIMED_EPOCHS: Map = Map::new("last_claimed_epoch"); + match config.expiration_balance { + Some(balance) => { + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); -/// A map of epochs to prop count -pub const EPOCH_PROPOSAL_COUNT: Map = Map::new("epoch_proposal_count"); + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) + } + None => Err(ContractError::NotExpired { + expiration: config.expiration, + }), + } +} + +/// A method to load the expected reward information +/// The expected reward method can differ from the actual reward, because the balance is saved in state after expiration +pub fn expected_reward(deps: Deps, env: Env, addr: &Addr) -> Result { + let config = CONFIG.load(deps.storage)?; -/// A map of epochs to total vote count -pub const EPOCH_TOTAL_VOTE_COUNT: Map = Map::new("epoch_total_vote_count"); + // Get the voting incentives balance + let balance = config + .denom + .query_balance(&deps.querier, &env.contract.address)?; -/// A map of user addresses + epoch to vote count -pub const USER_EPOCH_VOTE_COUNT: Map<(Addr, u64), u64> = Map::new("user_epoch_vote_count"); + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); + + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) +} + +fn calculate_reward( + total_votes: Uint128, + user_votes: Uint128, + balance: Uint128, +) -> Result { + if balance.is_zero() || user_votes.is_zero() || total_votes.is_zero() { + return Ok(Uint128::zero()); + } + + balance.checked_div_floor((user_votes, total_votes)) +} From f0c494b5552732d62220c6a68aca2154a01acbdf Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 15:55:33 -0600 Subject: [PATCH 13/47] Handle revoting and update readme's --- .../dao-proposal-incentives/README.md | 29 ++++++++- .../external/dao-voting-incentives/README.md | 42 +++++++----- .../dao-voting-incentives/src/execute.rs | 65 +++++++++++-------- .../dao-voting-incentives/src/state.rs | 3 + 4 files changed, 92 insertions(+), 47 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 106344544..f63d7b00a 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -3,8 +3,31 @@ [![dao-proposal-incentives on crates.io](https://img.shields.io/crates/v/dao-proposal-incentives.svg?logo=rust)](https://crates.io/crates/dao-proposal-incentives) [![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) -Allows for DAOs to offer incentives for making successful proposals. +This contract enables DAO's to incentivize members for making successful proposals. By integrating this contract, DAO's can automatically reward members whose proposals are successfully passed, using either native tokens or CW20 tokens. -To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module, and the DAO must be the `owner` of this contract. When someone successfully passes a proposal the specified rewards are automatically paid out. +## Instantiate -The incentives can be configured as native or cw20 tokens, and the award is determined by the configuration at the passed proposal's `start_time`. \ No newline at end of file +To instantiate the contract, provide the following parameters: + +- `owner`: The DAO sending this contract proposal hooks. +- `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure. + +## Setup + +- This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules. +- The DAO must be set as the `owner` of this contract to manage incentives and ownership. + +## Execute + +- **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals. +- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. +- **UpdateProposalIncentives { proposal_incentives: ProposalIncentivesUnchecked }**: Updates the incentives configuration. This allows the DAO to modify the rewards for successful proposals. +- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. + +## Query + +- **ProposalIncentives { height: Option }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time. + +## Configuration + +The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. \ No newline at end of file diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index df486cb0c..dbb0da0e9 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,24 +1,32 @@ -# dao-voting-incentives +This contract enables DAOs to offer incentives for voting on DAO proposals. By rewarding active voters, DAOs can encourage greater community involvement and decision-making. -[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) -[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) +## Instantiate -Allows for DAOs to offer incentives for voting on DAO proposals. +To instantiate the contract, provide the following parameters: -When creating this contract, the DAO specifies an `epoch_duration` and an amount to pay out per epoch. Then, the DAO needs to add this contract as a `VoteHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When DAO members vote, this contract keeps track of the proposals and who voted. +- `owner`: The DAO sending this contract voting hooks. +- `denom`: The denomination of the tokens to distribute as rewards. +- `expiration`: The expiration of the voting incentives period, defining how long the incentives are active. -At the end of the epoch, rewards are payable as follows: +## Configuration -`` -rewards = (user vote count / prop count) / total_vote_count * voting incentives -`` +- This contract should be added as a `VoteHook` to either the `dao-proposal-single` or `dao-proposal-multiple` proposal modules. +- The DAO must be set as the `owner` of this contract to manage incentives and ownership. -If no proposals happen during an epoch, no rewards are paid out. +If no votes are cast during the voting incentives period, then the contract's funds are sent to the `owner` on expiration. -## TODO -- [ ] Unit and Integration tests with a full DAO -- [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) -- [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. -- [ ] Support Cw20. -- [ ] Use `cw-ownable` to configure a contract owner who can update the voting incentives config. -- [ ] Add more info to the readme and delete this TODO section. +Rewards for a user are determined as such: `reward(user) = votes(user) * contract's balance / total votes` + +## Execute + +- **VoteHook(VoteHookMsg)**: Triggered when a new vote is cast. This is used to track voting activity and allocate rewards accordingly. +- **Claim {}**: Allows voters to claim their rewards after expiration. +- **Expire {}**: Expires the voting incentives period, allowing voters to claim rewards. +- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. +- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. + +## Query + +- **Config {}**: Returns the configuration of the voting incentives. +- **Rewards { address: String }**: Queries the claimable rewards for a specific address. +- **ExpectedRewards { address: String }**: Estimates the expected rewards for a specific address, based on current votes. diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index df5a75205..bed6fe22f 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -9,7 +9,7 @@ use dao_interface::{ }; use crate::{ - state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_VOTE_COUNT}, + state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_PROPOSAL_HAS_VOTED, USER_VOTE_COUNT}, ContractError, }; @@ -113,32 +113,42 @@ pub fn vote_hook( // Check if the vote came from a proposal at or after the start of the voting incentives if proposal_info.start_height >= config.start_height { - // Increment counts - let user_votes = USER_VOTE_COUNT.update( - deps.storage, - &voter, - |x| -> StdResult { - Ok(x.unwrap_or_default().checked_add(Uint128::one())?) - }, - )?; - config.total_votes = config.total_votes.checked_add(Uint128::one())?; - CONFIG.save(deps.storage, &config)?; - - // Set attributes - attrs = vec![ - Attribute { - key: "total_votes".to_string(), - value: config.total_votes.to_string(), - }, - Attribute { - key: "user_votes".to_string(), - value: user_votes.to_string(), - }, - Attribute { - key: "user".to_string(), - value: voter.to_string(), - }, - ]; + // Check if the user has already voted for the proposal + if !USER_PROPOSAL_HAS_VOTED.has(deps.storage, (&voter, proposal_id)) { + // Increment counts + let user_votes = USER_VOTE_COUNT.update( + deps.storage, + &voter, + |x| -> StdResult { + Ok(x.unwrap_or_default().checked_add(Uint128::one())?) + }, + )?; + config.total_votes = config.total_votes.checked_add(Uint128::one())?; + CONFIG.save(deps.storage, &config)?; + + // Set has voted + USER_PROPOSAL_HAS_VOTED.save( + deps.storage, + (&voter, proposal_id), + &true, + )?; + + // Set attributes + attrs = vec![ + Attribute { + key: "total_votes".to_string(), + value: config.total_votes.to_string(), + }, + Attribute { + key: "user_votes".to_string(), + value: user_votes.to_string(), + }, + Attribute { + key: "user".to_string(), + value: voter.to_string(), + }, + ]; + } } } } @@ -187,6 +197,7 @@ pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result = Map::new("user_vote_count"); +/// A map of user address with proposal id to has voted value +/// This map is useful for cases where a proposal module allows revoting, so users cannot spam votes for more rewards +pub const USER_PROPOSAL_HAS_VOTED: Map<(&Addr, u64), bool> = Map::new("user_proposal_has_voted"); /// The voting incentives config pub const CONFIG: Item = Item::new("config"); /// A cache of generic proposal information (proposal_module, proposal_id) From 1c3d428cf45df5c451c6b2308daaed33bf85a72f Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 15:59:11 -0600 Subject: [PATCH 14/47] Update README.md --- contracts/external/dao-voting-incentives/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index dbb0da0e9..645fcb2b2 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,3 +1,8 @@ +# dao-voting-incentives + +[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) + This contract enables DAOs to offer incentives for voting on DAO proposals. By rewarding active voters, DAOs can encourage greater community involvement and decision-making. ## Instantiate From 86c85f54c8b3c9d831ae77bb892ef68137770e9d Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Thu, 8 Feb 2024 12:54:22 -0600 Subject: [PATCH 15/47] Work on voting tests I think there's a bug in the removal of multiple hooks at the same time --- Cargo.lock | 3 + Cargo.toml | 1 + .../dao-proposal-incentives/README.md | 8 +- .../dao-proposal-incentives/src/tests.rs | 59 +-- .../external/dao-voting-incentives/Cargo.toml | 3 + .../dao-voting-incentives/src/contract.rs | 7 + .../external/dao-voting-incentives/src/lib.rs | 3 + .../external/dao-voting-incentives/src/msg.rs | 3 + .../dao-voting-incentives/src/query.rs | 12 +- .../dao-voting-incentives/src/tests.rs | 470 ++++++++++++++++++ packages/dao-testing/Cargo.toml | 3 +- packages/dao-testing/src/contracts.rs | 14 +- 12 files changed, 541 insertions(+), 45 deletions(-) create mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index efef129ec..2e6dfc42d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2012,6 +2012,7 @@ dependencies = [ "dao-voting-cw4", "dao-voting-cw721-roles", "dao-voting-cw721-staked", + "dao-voting-incentives", "dao-voting-token-staked", "osmosis-std", "osmosis-test-tube", @@ -2173,6 +2174,8 @@ dependencies = [ "dao-dao-core", "dao-hooks", "dao-interface", + "dao-proposal-single", + "dao-testing", "dao-voting 2.4.0", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 634c38d94..bd8e44284 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,6 +117,7 @@ dao-voting-cw20-staked = { path = "./contracts/voting/dao-voting-cw20-staked", v dao-voting-cw4 = { path = "./contracts/voting/dao-voting-cw4", version = "2.4.0" } dao-voting-cw721-roles = { path = "./contracts/voting/dao-voting-cw721-roles", version = "2.4.0" } dao-voting-cw721-staked = { path = "./contracts/voting/dao-voting-cw721-staked", version = "2.4.0" } +dao-voting-incentives = { path = "./contracts/external/dao-voting-incentives", version = "2.4.0" } dao-voting-token-staked = { path = "./contracts/voting/dao-voting-token-staked", version = "2.4.0" } # v1 dependencies. used for state migrations. diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index f63d7b00a..45bd9e0db 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -12,11 +12,13 @@ To instantiate the contract, provide the following parameters: - `owner`: The DAO sending this contract proposal hooks. - `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure. -## Setup +## Configuration - This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules. - The DAO must be set as the `owner` of this contract to manage incentives and ownership. +The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. + ## Execute - **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals. @@ -27,7 +29,3 @@ To instantiate the contract, provide the following parameters: ## Query - **ProposalIncentives { height: Option }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time. - -## Configuration - -The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 6afc2dedf..2adca6808 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -2,17 +2,15 @@ use std::vec; use cosmwasm_std::{ testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Uint128, WasmMsg, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, }; use cw20::Cw20Coin; use cw_denom::{CheckedDenom, UncheckedDenom}; -use cw_multi_test::{ - error::AnyResult, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, -}; +use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; use cw_ownable::Ownership; use dao_testing::{ - contracts::{dao_proposal_incentives_contract, proposal_single_contract}, + contracts::{cw20_base_contract, dao_proposal_incentives_contract, proposal_single_contract}, helpers::instantiate_with_cw4_groups_governance, }; use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; @@ -35,15 +33,6 @@ struct Context { dao_proposal_incentives_code_id: u64, } -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn get_context() -> Context { // Set up app with native balances let mut app = AppBuilder::default().build(|router, _, storage| { @@ -352,28 +341,26 @@ pub fn test_hook() { assert!(result.is_ok()); // Propose adding a hook - context - .app - .execute_contract( - Addr::unchecked(ADDR1), - context.proposal_single_addr.clone(), - &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { - title: "Add proposal hook".to_string(), - description: "Adding a proposal hook to test the dao_proposal_incentives contract" - .to_string(), - msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: context.proposal_single_addr.to_string(), - msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { - address: dao_proposal_incentives_addr.to_string(), - }) - .unwrap(), - funds: vec![], - })], - proposer: None, - }), - &[], - ) - .unwrap(); + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add proposal hook".to_string(), + description: "Adding a proposal hook to test the dao_proposal_incentives contract" + .to_string(), + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { + address: dao_proposal_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + })], + proposer: None, + }), + &[], + ); + assert!(result.is_ok()); // Vote and execute the proposal to add the proposal hook vote_yes_on_proposal(&mut context, 1u64).unwrap(); diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index fbeccc8c0..be6d63c19 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -36,3 +36,6 @@ cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } cw-hooks = { workspace = true } +dao-testing = { workspace = true } +dao-hooks = { workspace = true } +dao-proposal-single = { workspace = true, features = ["library"] } \ No newline at end of file diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 32ca6e86b..75d5b6050 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -5,6 +5,7 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; use cw_ownable::get_ownership; +use cw_utils::Expiration; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; @@ -33,6 +34,11 @@ pub fn instantiate( if msg.expiration.is_expired(&env.block) { return Err(ContractError::AlreadyExpired {}); } + if let Expiration::Never {} = msg.expiration { + return Err(ContractError::NotExpired { + expiration: Expiration::Never {}, + }); + } // Save voting incentives config CONFIG.save( @@ -81,6 +87,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } QueryMsg::Config {} => to_json_binary(&query::config(deps)?), QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), + QueryMsg::Votes { address } => to_json_binary(&query::votes(deps, address)?), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index d2f25785c..bed930ba1 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -7,4 +7,7 @@ pub mod msg; pub mod query; pub mod state; +#[cfg(test)] +mod tests; + pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 1937ab74b..4eb0b7af4 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -42,6 +42,9 @@ pub enum QueryMsg { /// Returns the expected rewards for the given address #[returns(RewardResponse)] ExpectedRewards { address: String }, + /// Returns the votes count for the given address + #[returns(Uint128)] + Votes { address: String }, } #[cw_serde] diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs index 96a6877ea..dcee2772f 100644 --- a/contracts/external/dao-voting-incentives/src/query.rs +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -1,8 +1,8 @@ -use cosmwasm_std::{Deps, Env, StdError, StdResult}; +use cosmwasm_std::{Deps, Env, StdError, StdResult, Uint128}; use crate::{ msg::RewardResponse, - state::{self, Config, CONFIG}, + state::{self, Config, CONFIG, USER_VOTE_COUNT}, }; pub fn rewards(deps: Deps, address: String) -> StdResult { @@ -21,3 +21,11 @@ pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult StdResult { CONFIG.load(deps.storage) } + +pub fn votes(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + Ok(USER_VOTE_COUNT + .may_load(deps.storage, &address)? + .unwrap_or_default()) +} diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs new file mode 100644 index 000000000..de63a8419 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -0,0 +1,470 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env}, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, +}; + +use cw20::{Cw20Coin, Cw20ReceiveMsg}; +use cw_denom::UncheckedDenom; +use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; +use cw_utils::Expiration; +use dao_testing::{ + contracts::{cw20_base_contract, dao_voting_incentives_contract, proposal_single_contract}, + helpers::instantiate_with_cw4_groups_governance, +}; +use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; + +use crate::{ + contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + state::Config, +}; + +const ADMIN: &str = "admin"; +const ADDR1: &str = "addr1"; +const ADDR2: &str = "addr2"; +const DENOM: &str = "juno"; + +struct Context { + app: App, + cw20_addr: Addr, + proposal_single_addr: Addr, + dao_addr: Addr, + dao_voting_incentives_code_id: u64, +} + +fn get_context() -> Context { + // Set up app with native balances + let mut app = AppBuilder::default().build(|router, _, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked(ADMIN), + vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + }); + + // Set up cw20 with balances + let cw20_code_id = app.store_code(cw20_base_contract()); + let cw20_addr = app + .instantiate_contract( + cw20_code_id, + Addr::unchecked(ADMIN), + &cw20_base::msg::InstantiateMsg { + name: "cw20 token".to_string(), + symbol: "cwtoken".to_string(), + decimals: 6, + initial_balances: vec![Cw20Coin { + address: ADMIN.to_string(), + amount: Uint128::new(1000), + }], + mint: None, + marketing: None, + }, + &[], + "cw20-base", + None, + ) + .unwrap(); + + // Set up dao + let proposal_single_code_id = app.store_code(proposal_single_contract()); + let dao_addr = instantiate_with_cw4_groups_governance( + &mut app, + proposal_single_code_id, + to_json_binary(&dao_proposal_single::msg::InstantiateMsg { + threshold: Threshold::AbsolutePercentage { + percentage: dao_voting::threshold::PercentageThreshold::Majority {}, + }, + max_voting_period: cw_utils::Duration::Height(10u64), + min_voting_period: None, + only_members_execute: false, + allow_revoting: false, + pre_propose_info: dao_voting::pre_propose::PreProposeInfo::AnyoneMayPropose {}, + close_proposal_on_execution_failure: true, + veto: None, + }) + .unwrap(), + Some(vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::one(), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::one(), + }, + ]), + ); + + // Get proposal single addr + let proposal_modules: Vec = app + .wrap() + .query_wasm_smart( + dao_addr.clone(), + &dao_interface::msg::QueryMsg::ProposalModules { + start_after: None, + limit: Some(1u32), + }, + ) + .unwrap(); + assert!(!proposal_modules.is_empty()); + let proposal_single_addr = proposal_modules.first().unwrap().address.clone(); + + // Set up dao voting incentives code id + let dao_voting_incentives_code_id = app.store_code(dao_voting_incentives_contract()); + + Context { + app, + cw20_addr, + dao_addr, + dao_voting_incentives_code_id, + proposal_single_addr, + } +} + +fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> Vec> { + vec![ + context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &[], + ), + context.app.execute_contract( + Addr::unchecked(ADDR2), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &[], + ), + ] +} + +fn execute_proposal(context: &mut Context, proposal_id: u64) { + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Execute { proposal_id }, + &[], + ) + .unwrap(); +} + +#[test] +pub fn test_instantiate_validation() { + let mut context = get_context(); + + // Check already expired is error + let result = context.app.instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(1u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ); + assert!(result.is_err()); + + // Check expiration never is error + let result = context.app.instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::Never {}, + }, + &[], + "dao_voting_incentives".to_string(), + None, + ); + assert!(result.is_err()); +} + +#[test] +pub fn test_hooks() { + let mut context = get_context(); + + // Create the voting incentives contract for native + // The expiration is 10 blocks from start (12345 height) + let dao_voting_incentives_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ) + .unwrap(); + + // Also create a parallel voting incentives contract for cw20 + let dao_voting_incentives_cw20_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Cw20(context.cw20_addr.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives_cw20".to_string(), + None, + ) + .unwrap(); + + context.app.update_block(|x| x.height += 1); + + // Execute fails - unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::VoteHook(dao_hooks::vote::VoteHookMsg::NewVote { + proposal_id: 1u64, + voter: ADMIN.to_string(), + vote: "a fake vote".to_string(), + }), + &[], + ); + assert!(result.is_err()); + + // Fund the incentives contracts for 1000 + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &[Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + context.cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::Send { + contract: dao_voting_incentives_cw20_addr.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }, + &[], + ); + assert!(result.is_ok()); + + // Assert the cw20 voting incentives do not accept a random cw20 token + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: ADMIN.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }), + &[], + ); + assert!(result.is_err()); + + // Propose adding both hooks + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add vote hooks".to_string(), + description: "Adding 2 voting hooks to test the dao_voting_incentives contract" + .to_string(), + msgs: vec![ + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddVoteHook { + address: dao_voting_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + }), + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddVoteHook { + address: dao_voting_incentives_cw20_addr.to_string(), + }) + .unwrap(), + funds: vec![], + }), + ], + proposer: None, + }), + &[], + ); + assert!(result.is_ok()); + + // Vote and execute the proposal to add the vote hooks + let results = vote_yes_on_proposal(&mut context, 1u64); + for result in results { + assert!(result.is_ok()); + } + execute_proposal(&mut context, 1u64); + + // Query for the newly-established hooks + let result: cw_hooks::HooksResponse = context + .app + .wrap() + .query_wasm_smart( + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::QueryMsg::VoteHooks {}, + ) + .unwrap(); + assert!(result + .hooks + .contains(&dao_voting_incentives_addr.to_string())); + assert!(result + .hooks + .contains(&dao_voting_incentives_cw20_addr.to_string())); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &[], + ) + .unwrap(); + + // Trigger a vote hook + let results = vote_yes_on_proposal(&mut context, 2u64); + for result in results { + assert!(result.is_ok()); + } + + // Assert that the vote hook has incremented vote counts + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_addr.clone(), + &QueryMsg::Votes { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_addr.clone(), + &QueryMsg::Votes { + address: ADDR2.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_cw20_addr.clone(), + &QueryMsg::Votes { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_cw20_addr.clone(), + &QueryMsg::Votes { + address: ADDR2.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let config: Config = context + .app + .wrap() + .query_wasm_smart(dao_voting_incentives_addr.clone(), &QueryMsg::Config {}) + .unwrap(); + assert_eq!(config.total_votes, Uint128::new(2)); + + // Blocks have passed the voting incentives' expirations + context.app.update_block(|x| x.height += 100); + + // Creating another proposal and voting should still succeed but unregister these vote hooks + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &[], + ) + .unwrap(); + let results = vote_yes_on_proposal(&mut context, 3u64); + for (i, result) in results.iter().enumerate() { + assert!(result.is_ok()); + if i == 0 { + // Vote hooks should unregister on the first instance of expiration + let events = &result.as_ref().unwrap().events; + assert!(events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_vote_hook" + && y.value == format!("{0}:0", dao_voting_incentives_addr.clone())))); + assert!(events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_vote_hook" + && y.value == format!("{0}:1", dao_voting_incentives_cw20_addr.clone())))); + } + } +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg::FromCompatible {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index 73df2521b..4609d2d9d 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -58,4 +58,5 @@ dao-voting-cw721-roles = { workspace = true } dao-voting-token-staked = { workspace = true } voting-v1 = { workspace = true } stake-cw20-v03 = { workspace = true } -dao-proposal-incentives = { workspace = true } \ No newline at end of file +dao-proposal-incentives = { workspace = true } +dao-voting-incentives = { workspace = true } \ No newline at end of file diff --git a/packages/dao-testing/src/contracts.rs b/packages/dao-testing/src/contracts.rs index 8ab5ab9ee..eae33ecc7 100644 --- a/packages/dao-testing/src/contracts.rs +++ b/packages/dao-testing/src/contracts.rs @@ -212,7 +212,19 @@ pub fn dao_proposal_incentives_contract() -> Box> { dao_proposal_incentives::contract::execute, dao_proposal_incentives::contract::instantiate, dao_proposal_incentives::contract::query, - ); + ) + .with_migrate(dao_proposal_incentives::contract::migrate); + + Box::new(contract) +} + +pub fn dao_voting_incentives_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_incentives::contract::execute, + dao_voting_incentives::contract::instantiate, + dao_voting_incentives::contract::query, + ) + .with_migrate(dao_voting_incentives::contract::migrate); Box::new(contract) } From 01eedd686caa033ea8573f47f13011a7acfbd44c Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Fri, 9 Feb 2024 14:59:33 -0600 Subject: [PATCH 16/47] Fix for simultaneous hook error handling --- .../dao-proposal-multiple/src/contract.rs | 21 +++++++++-- .../dao-proposal-multiple/src/state.rs | 4 +++ .../dao-proposal-single/src/contract.rs | 22 ++++++++++-- .../proposal/dao-proposal-single/src/state.rs | 4 +++ packages/cw-hooks/src/lib.rs | 35 +++++++++++++++++++ 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/contracts/proposal/dao-proposal-multiple/src/contract.rs b/contracts/proposal/dao-proposal-multiple/src/contract.rs index 2788e3f2b..a768c4f2c 100644 --- a/contracts/proposal/dao-proposal-multiple/src/contract.rs +++ b/contracts/proposal/dao-proposal-multiple/src/contract.rs @@ -28,6 +28,7 @@ use dao_voting::{ voting::{get_total_power, get_voting_power, validate_voting_period}, }; +use crate::state::{REMOVED_PROPOSAL_HOOKS_BY_INDEX, REMOVED_VOTE_HOOKS_BY_INDEX}; use crate::{msg::MigrateMsg, state::CREATION_POLICY}; use crate::{ msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, @@ -261,6 +262,7 @@ pub fn execute_propose( PROPOSALS.save(deps.storage, id, &proposal)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let hooks = new_proposal_hooks(PROPOSAL_HOOKS, deps.storage, id, proposer.as_str())?; Ok(Response::default() @@ -324,6 +326,7 @@ pub fn execute_veto( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -418,6 +421,8 @@ pub fn execute_vote( prop.update_status(&env.block)?; PROPOSALS.save(deps.storage, proposal_id, &prop)?; let new_status = prop.status; + + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let change_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -425,6 +430,8 @@ pub fn execute_vote( old_status.to_string(), new_status.to_string(), )?; + + REMOVED_VOTE_HOOKS_BY_INDEX.remove(deps.storage); let vote_hooks = new_vote_hooks( VOTE_HOOKS, deps.storage, @@ -536,6 +543,7 @@ pub fn execute_execute( Response::default() }; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -579,6 +587,7 @@ pub fn execute_close( PROPOSALS.save(deps.storage, proposal_id, &prop)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -984,11 +993,19 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - let addr = PROPOSAL_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = PROPOSAL_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_PROPOSAL_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_proposal_hook", format!("{addr}:{idx}"))) } TaggedReplyId::FailedVoteHook(idx) => { - let addr = VOTE_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = VOTE_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_VOTE_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed vote hook", format!("{addr}:{idx}"))) } TaggedReplyId::PreProposeModuleInstantiation => { diff --git a/contracts/proposal/dao-proposal-multiple/src/state.rs b/contracts/proposal/dao-proposal-multiple/src/state.rs index 2261f6d03..26906d5cf 100644 --- a/contracts/proposal/dao-proposal-multiple/src/state.rs +++ b/contracts/proposal/dao-proposal-multiple/src/state.rs @@ -69,6 +69,10 @@ pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("ballots"); pub const PROPOSAL_HOOKS: Hooks = Hooks::new("proposal_hooks"); /// Consumers of vote hooks. pub const VOTE_HOOKS: Hooks = Hooks::new("vote_hooks"); +/// Lists of hook indexes removed to adjust for in submsg replies +pub const REMOVED_VOTE_HOOKS_BY_INDEX: Item> = Item::new("removed_vote_hooks_by_index"); +pub const REMOVED_PROPOSAL_HOOKS_BY_INDEX: Item> = + Item::new("removed_proposal_hooks_by_index"); /// The address of the pre-propose module associated with this /// proposal module (if any). pub const CREATION_POLICY: Item = Item::new("creation_policy"); diff --git a/contracts/proposal/dao-proposal-single/src/contract.rs b/contracts/proposal/dao-proposal-single/src/contract.rs index 3965f2b40..6a7a87eea 100644 --- a/contracts/proposal/dao-proposal-single/src/contract.rs +++ b/contracts/proposal/dao-proposal-single/src/contract.rs @@ -27,7 +27,9 @@ use dao_voting::voting::{get_total_power, get_voting_power, validate_voting_peri use crate::msg::MigrateMsg; use crate::proposal::{next_proposal_id, SingleChoiceProposal}; -use crate::state::{Config, CREATION_POLICY}; +use crate::state::{ + Config, CREATION_POLICY, REMOVED_PROPOSAL_HOOKS_BY_INDEX, REMOVED_VOTE_HOOKS_BY_INDEX, +}; use crate::v1_state::{ v1_duration_to_v2, v1_expiration_to_v2, v1_status_to_v2, v1_threshold_to_v2, v1_votes_to_v2, }; @@ -252,6 +254,7 @@ pub fn execute_propose( PROPOSALS.save(deps.storage, id, &proposal)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let hooks = new_proposal_hooks(PROPOSAL_HOOKS, deps.storage, id, proposer.as_str())?; Ok(Response::default() @@ -315,6 +318,7 @@ pub fn execute_veto( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -427,6 +431,7 @@ pub fn execute_execute( }; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -523,6 +528,7 @@ pub fn execute_vote( PROPOSALS.save(deps.storage, proposal_id, &prop)?; let new_status = prop.status; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let change_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -531,6 +537,7 @@ pub fn execute_vote( new_status.to_string(), )?; + REMOVED_VOTE_HOOKS_BY_INDEX.remove(deps.storage); let vote_hooks = new_vote_hooks( VOTE_HOOKS, deps.storage, @@ -601,6 +608,7 @@ pub fn execute_close( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -1068,11 +1076,19 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - let addr = PROPOSAL_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = PROPOSAL_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_PROPOSAL_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_proposal_hook", format!("{addr}:{idx}"))) } TaggedReplyId::FailedVoteHook(idx) => { - let addr = VOTE_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = VOTE_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_VOTE_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_vote_hook", format!("{addr}:{idx}"))) } TaggedReplyId::PreProposeModuleInstantiation => { diff --git a/contracts/proposal/dao-proposal-single/src/state.rs b/contracts/proposal/dao-proposal-single/src/state.rs index 88e748b51..55fcf3cb6 100644 --- a/contracts/proposal/dao-proposal-single/src/state.rs +++ b/contracts/proposal/dao-proposal-single/src/state.rs @@ -74,6 +74,10 @@ pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("ballots"); pub const PROPOSAL_HOOKS: Hooks = Hooks::new("proposal_hooks"); /// Consumers of vote hooks. pub const VOTE_HOOKS: Hooks = Hooks::new("vote_hooks"); +/// Lists of hook indexes removed to adjust for in submsg replies +pub const REMOVED_VOTE_HOOKS_BY_INDEX: Item> = Item::new("removed_vote_hooks_by_index"); +pub const REMOVED_PROPOSAL_HOOKS_BY_INDEX: Item> = + Item::new("removed_proposal_hooks_by_index"); /// The address of the pre-propose module associated with this /// proposal module (if any). pub const CREATION_POLICY: Item = Item::new("creation_policy"); diff --git a/packages/cw-hooks/src/lib.rs b/packages/cw-hooks/src/lib.rs index fdbf43577..6f08a497d 100644 --- a/packages/cw-hooks/src/lib.rs +++ b/packages/cw-hooks/src/lib.rs @@ -102,6 +102,41 @@ impl<'a> Hooks<'a> { let hooks = hooks.into_iter().map(String::from).collect(); Ok(HooksResponse { hooks }) } + + /// Use this method to remove a hook by index from a reply + /// The removed_hook_indexes should be cleared when submsgs are sent + pub fn remove_hook_by_index_from_reply( + &self, + storage: &mut dyn Storage, + index: u64, + removed_hook_indexes: Item>, + ) -> Result { + let adjusted_index = match removed_hook_indexes.may_load(storage)? { + Some(mut removed_indexes) => { + let mut result = index; + + for removed_index in removed_indexes.iter() { + if removed_index < &index { + result -= 1; + } + } + + // Update the removed indexes + removed_indexes.push(index); + removed_hook_indexes.save(storage, &removed_indexes)?; + + result + } + None => { + // Set the removed indexes + removed_hook_indexes.save(storage, &vec![index])?; + + index + } + }; + + self.remove_hook_by_index(storage, adjusted_index) + } } #[cfg(test)] From e4477dfcad430b514d2ea1cf562dc266a7cfa9b8 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Sat, 10 Feb 2024 15:31:30 -0600 Subject: [PATCH 17/47] Wrap up tests for voting incentives --- Cargo.lock | 1 - .../dao-voting-incentives/src/error.rs | 3 + .../dao-voting-incentives/src/execute.rs | 5 + .../dao-voting-incentives/src/state.rs | 2 +- .../dao-voting-incentives/src/tests.rs | 141 +++++++++++++++++- .../proposal/dao-proposal-single/Cargo.toml | 1 - 6 files changed, 149 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e6dfc42d..e04c97036 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1930,7 +1930,6 @@ dependencies = [ "dao-interface", "dao-pre-propose-base", "dao-pre-propose-single", - "dao-proposal-incentives", "dao-testing", "dao-voting 0.1.0", "dao-voting 2.4.0", diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 15b5024ad..64b3298b3 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -38,4 +38,7 @@ pub enum ContractError { expected: CheckedDenom, received: CheckedDenom, }, + + #[error("NothingToClaim")] + NothingToClaim {}, } diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index bed6fe22f..22a16935b 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -14,6 +14,11 @@ use crate::{ }; pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + // Ensure the user has something to claim + if !USER_VOTE_COUNT.has(deps.storage, &info.sender) { + return Err(ContractError::NothingToClaim {}); + } + // Get reward information let reward = reward(deps.as_ref(), &info.sender)?; diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 14ac95b50..09fdbfbac 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -87,5 +87,5 @@ fn calculate_reward( return Ok(Uint128::zero()); } - balance.checked_div_floor((user_votes, total_votes)) + balance.checked_mul_floor((user_votes, total_votes)) } diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index de63a8419..2f9f0c531 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, }; -use cw20::{Cw20Coin, Cw20ReceiveMsg}; +use cw20::{BalanceResponse, Cw20Coin, Cw20QueryMsg, Cw20ReceiveMsg}; use cw_denom::UncheckedDenom; use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; use cw_utils::Expiration; @@ -457,6 +457,145 @@ pub fn test_hooks() { && y.value == format!("{0}:1", dao_voting_incentives_cw20_addr.clone())))); } } + + // Expire the vote hooks + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + + // Ensure expire errors if already expired + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_err()); + + // Random person cannot claim + let result = context.app.execute_contract( + Addr::unchecked("random"), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_err()); + + // User claims rewards + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_ok()); + + // User balance has increased by 500, because 1000 reward with 2 voters during the period + let balance = context + .app + .wrap() + .query_balance(Addr::unchecked(ADDR1), DENOM) + .unwrap(); + assert_eq!(balance.amount, Uint128::new(500)); + + // User cannot claim again + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_err()); + + // User claims rewards cw20 + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_ok()); + + // User balance has increased by 500, because 1000 reward with 2 voters during the period + let balance_response: BalanceResponse = context + .app + .wrap() + .query_wasm_smart( + context.cw20_addr, + &Cw20QueryMsg::Balance { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance_response.balance, Uint128::new(500)); +} + +#[test] +pub fn test_expire_sends_funds_to_owner() { + let mut context = get_context(); + + // Create the voting incentives contract for native + // The expiration is 10 blocks from start (12345 height) + let dao_voting_incentives_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ) + .unwrap(); + + // Fund the incentives contracts for 1000 + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &[Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + + // Blocks have passed the voting incentives' expirations + context.app.update_block(|x| x.height += 100); + + // Expire the vote hooks + // No votes were received during the period, so the funds should be sent to the owner on expiration + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + + // Ensure funds were sent to the DAO + let balance = context + .app + .wrap() + .query_balance(context.dao_addr, DENOM) + .unwrap(); + assert_eq!(balance.amount, Uint128::new(1000)); } #[test] diff --git a/contracts/proposal/dao-proposal-single/Cargo.toml b/contracts/proposal/dao-proposal-single/Cargo.toml index 6bc126fa9..06170dd00 100644 --- a/contracts/proposal/dao-proposal-single/Cargo.toml +++ b/contracts/proposal/dao-proposal-single/Cargo.toml @@ -54,4 +54,3 @@ cw721-base = { workspace = true } cw4 = { workspace = true } cw4-group = { workspace = true } cw-core-v1 = { workspace = true, features = ["library"] } -dao-proposal-incentives = { workspace = true } From 30bfeabaaa8e5e15f2515fd115cddd8cd9d33768 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 13 Feb 2024 08:59:15 -0600 Subject: [PATCH 18/47] Combine rewards queries --- .../schema/dao-voting-incentives.json | 114 ++++++++---------- .../dao-voting-incentives/src/contract.rs | 5 +- .../dao-voting-incentives/src/execute.rs | 9 +- .../external/dao-voting-incentives/src/msg.rs | 5 +- .../dao-voting-incentives/src/query.rs | 10 +- .../dao-voting-incentives/src/state.rs | 47 +++----- 6 files changed, 77 insertions(+), 113 deletions(-) diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index 0bfbb8c10..70ef14eda 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -183,6 +183,18 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false } ], "definitions": { @@ -237,6 +249,31 @@ } ] }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, "Expiration": { "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", "oneOf": [ @@ -292,6 +329,10 @@ } ] }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, "Uint64": { "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", "type": "string" @@ -353,7 +394,7 @@ "additionalProperties": false }, { - "description": "Returns the claimable rewards for the given address.", + "description": "Returns the rewards for the given address.", "type": "object", "required": [ "rewards" @@ -375,13 +416,13 @@ "additionalProperties": false }, { - "description": "Returns the expected rewards for the given address", + "description": "Returns the votes count for the given address", "type": "object", "required": [ - "expected_rewards" + "votes" ], "properties": { - "expected_rewards": { + "votes": { "type": "object", "required": [ "address" @@ -478,65 +519,6 @@ }, "additionalProperties": false }, - "expected_rewards": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RewardResponse", - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "$ref": "#/definitions/CheckedDenom" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "CheckedDenom": { - "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", - "oneOf": [ - { - "description": "A native (bank module) asset.", - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "A cw20 asset.", - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, "ownership": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Ownership_for_String", @@ -690,6 +672,12 @@ "type": "string" } } + }, + "votes": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Uint128", + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" } } } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 75d5b6050..ec439fe57 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -81,10 +81,7 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, address)?), - QueryMsg::ExpectedRewards { address } => { - to_json_binary(&query::expected_rewards(deps, env, address)?) - } + QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, env, address)?), QueryMsg::Config {} => to_json_binary(&query::config(deps)?), QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), QueryMsg::Votes { address } => to_json_binary(&query::votes(deps, address)?), diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index 22a16935b..a4d312467 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -13,14 +13,14 @@ use crate::{ ContractError, }; -pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { +pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> Result { // Ensure the user has something to claim if !USER_VOTE_COUNT.has(deps.storage, &info.sender) { return Err(ContractError::NothingToClaim {}); } // Get reward information - let reward = reward(deps.as_ref(), &info.sender)?; + let reward = reward(deps.as_ref(), &env.contract.address, &info.sender)?; // If the user has rewards, then we should generate a message let mut msgs = vec![]; @@ -212,13 +212,16 @@ pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result Result { let config = CONFIG.load(deps.storage)?; // Do not accept unexpected cw20 + if config.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } match &config.denom { CheckedDenom::Native(_) => { return Err(ContractError::UnexpectedFunds { diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 4eb0b7af4..2b21e0711 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -36,12 +36,9 @@ pub enum QueryMsg { /// Returns the config #[returns(Config)] Config {}, - /// Returns the claimable rewards for the given address. + /// Returns the rewards for the given address. #[returns(RewardResponse)] Rewards { address: String }, - /// Returns the expected rewards for the given address - #[returns(RewardResponse)] - ExpectedRewards { address: String }, /// Returns the votes count for the given address #[returns(Uint128)] Votes { address: String }, diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs index dcee2772f..622180c2e 100644 --- a/contracts/external/dao-voting-incentives/src/query.rs +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -5,16 +5,10 @@ use crate::{ state::{self, Config, CONFIG, USER_VOTE_COUNT}, }; -pub fn rewards(deps: Deps, address: String) -> StdResult { +pub fn rewards(deps: Deps, env: Env, address: String) -> StdResult { let address = deps.api.addr_validate(&address)?; - state::reward(deps, &address).map_err(|x| StdError::GenericErr { msg: x.to_string() }) -} - -pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult { - let address = deps.api.addr_validate(&address)?; - - state::expected_reward(deps, env, &address) + state::reward(deps, &env.contract.address, &address) .map_err(|x| StdError::GenericErr { msg: x.to_string() }) } diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 09fdbfbac..3563e38f6 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Env, Uint128}; +use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Uint128}; use cw_denom::CheckedDenom; use cw_storage_plus::{Item, Map}; use cw_utils::Expiration; @@ -34,15 +34,25 @@ pub const GENERIC_PROPOSAL_INFO: Map<(&Addr, u64), GenericProposalInfo> = Map::new("generic_proposal_info"); /// A method to load reward information -pub fn reward(deps: Deps, addr: &Addr) -> Result { +pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result { let config = CONFIG.load(deps.storage)?; + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); + match config.expiration_balance { Some(balance) => { - // Get the user's votes - let user_votes = USER_VOTE_COUNT - .may_load(deps.storage, addr)? - .unwrap_or_default(); + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) + } + None => { + // Get the current voting incentives balance + let balance = config.denom.query_balance(&deps.querier, contract)?; // Calculate the reward Ok(RewardResponse { @@ -50,34 +60,9 @@ pub fn reward(deps: Deps, addr: &Addr) -> Result amount: calculate_reward(config.total_votes, user_votes, balance)?, }) } - None => Err(ContractError::NotExpired { - expiration: config.expiration, - }), } } -/// A method to load the expected reward information -/// The expected reward method can differ from the actual reward, because the balance is saved in state after expiration -pub fn expected_reward(deps: Deps, env: Env, addr: &Addr) -> Result { - let config = CONFIG.load(deps.storage)?; - - // Get the voting incentives balance - let balance = config - .denom - .query_balance(&deps.querier, &env.contract.address)?; - - // Get the user's votes - let user_votes = USER_VOTE_COUNT - .may_load(deps.storage, addr)? - .unwrap_or_default(); - - // Calculate the reward - Ok(RewardResponse { - denom: config.denom, - amount: calculate_reward(config.total_votes, user_votes, balance)?, - }) -} - fn calculate_reward( total_votes: Uint128, user_votes: Uint128, From 2816bebce58c4049a907f7643b00213c71148263 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 13 Feb 2024 21:16:50 -0600 Subject: [PATCH 19/47] Add is_claimable flag to reward response --- .../schema/dao-voting-incentives.json | 6 ++++- .../external/dao-voting-incentives/src/msg.rs | 1 + .../dao-voting-incentives/src/state.rs | 2 ++ .../dao-voting-incentives/src/tests.rs | 24 +++++++++++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index 70ef14eda..f2331d18e 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -620,7 +620,8 @@ "type": "object", "required": [ "amount", - "denom" + "denom", + "is_claimable" ], "properties": { "amount": { @@ -628,6 +629,9 @@ }, "denom": { "$ref": "#/definitions/CheckedDenom" + }, + "is_claimable": { + "type": "boolean" } }, "additionalProperties": false, diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 2b21e0711..72b1a6dd6 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -53,4 +53,5 @@ pub enum MigrateMsg { pub struct RewardResponse { pub denom: CheckedDenom, pub amount: Uint128, + pub is_claimable: bool, } diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 3563e38f6..7688ce408 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -48,6 +48,7 @@ pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result { @@ -58,6 +59,7 @@ pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result Date: Tue, 7 May 2024 20:54:10 -0500 Subject: [PATCH 20/47] Schemas and clippy fixes --- Cargo.lock | 8 +-- ci/bootstrap-env/src/main.rs | 3 +- ci/integration-tests/src/helpers/chain.rs | 3 +- .../dao-dao-core/schema/dao-dao-core.json | 69 +++++++++++++++++++ .../external/cw721-roles/src/contract.rs | 4 +- .../dao-proposal-incentives/Cargo.toml | 2 +- .../schema/dao-proposal-incentives.json | 2 +- .../dao-proposal-incentives/src/tests.rs | 3 + .../external/dao-voting-incentives/Cargo.toml | 2 +- .../schema/dao-voting-incentives.json | 2 +- .../dao-voting-incentives/src/tests.rs | 3 + .../schema/dao-proposal-condorcet.json | 50 ++++++++++++++ .../schema/dao-proposal-multiple.json | 50 ++++++++++++++ .../schema/dao-proposal-single.json | 50 ++++++++++++++ 14 files changed, 239 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 885603bc0..e5184d09a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1844,7 +1844,7 @@ dependencies = [ [[package]] name = "dao-proposal-incentives" -version = "2.4.0" +version = "2.4.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1862,7 +1862,7 @@ dependencies = [ "dao-interface", "dao-proposal-single", "dao-testing", - "dao-voting 2.4.0", + "dao-voting 2.4.2", "thiserror", ] @@ -2157,7 +2157,7 @@ dependencies = [ [[package]] name = "dao-voting-incentives" -version = "2.4.0" +version = "2.4.2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -2175,7 +2175,7 @@ dependencies = [ "dao-interface", "dao-proposal-single", "dao-testing", - "dao-voting 2.4.0", + "dao-voting 2.4.2", "thiserror", ] diff --git a/ci/bootstrap-env/src/main.rs b/ci/bootstrap-env/src/main.rs index c1c321c91..83d6b82c9 100644 --- a/ci/bootstrap-env/src/main.rs +++ b/ci/bootstrap-env/src/main.rs @@ -183,7 +183,8 @@ fn main() -> Result<()> { ); // Persist contract code_ids in local.yaml so we can use SKIP_CONTRACT_STORE locally to avoid having to re-store them again - cfg.contract_deploy_info = orc.contract_map.deploy_info().clone(); + cfg.contract_deploy_info + .clone_from(orc.contract_map.deploy_info()); fs::write( "ci/configs/cosm-orc/local.yaml", serde_yaml::to_string(&cfg)?, diff --git a/ci/integration-tests/src/helpers/chain.rs b/ci/integration-tests/src/helpers/chain.rs index 20b3d27d4..fd7445cde 100644 --- a/ci/integration-tests/src/helpers/chain.rs +++ b/ci/integration-tests/src/helpers/chain.rs @@ -99,7 +99,8 @@ fn global_setup() -> Cfg { .unwrap(); save_gas_report(&orc, &gas_report_dir); // persist stored code_ids in CONFIG, so we can reuse for all tests - cfg.contract_deploy_info = orc.contract_map.deploy_info().clone(); + cfg.contract_deploy_info + .clone_from(orc.contract_map.deploy_info()); } Cfg { diff --git a/contracts/dao-dao-core/schema/dao-dao-core.json b/contracts/dao-dao-core/schema/dao-dao-core.json index 3ada83c21..9ce1b683f 100644 --- a/contracts/dao-dao-core/schema/dao-dao-core.json +++ b/contracts/dao-dao-core/schema/dao-dao-core.json @@ -1796,6 +1796,27 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "proposal_module" + ], + "properties": { + "proposal_module": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Gets the active proposal modules associated with the contract.", "type": "object", @@ -3033,6 +3054,54 @@ } } }, + "proposal_module": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalModule", + "description": "Top level type describing a proposal module.", + "type": "object", + "required": [ + "address", + "prefix", + "status" + ], + "properties": { + "address": { + "description": "The address of the proposal module.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "prefix": { + "description": "The URL prefix of this proposal module as derived from the module ID. Prefixes are mapped to letters, e.g. 0 is 'A', and 26 is 'AA'.", + "type": "string" + }, + "status": { + "description": "The status of the proposal module, e.g. 'Enabled' or 'Disabled.'", + "allOf": [ + { + "$ref": "#/definitions/ProposalModuleStatus" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ProposalModuleStatus": { + "description": "The status of a proposal module.", + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + } + } + }, "proposal_module_count": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ProposalModuleCountResponse", diff --git a/contracts/external/cw721-roles/src/contract.rs b/contracts/external/cw721-roles/src/contract.rs index 833007e46..ea31936a1 100644 --- a/contracts/external/cw721-roles/src/contract.rs +++ b/contracts/external/cw721-roles/src/contract.rs @@ -319,7 +319,7 @@ pub fn execute_update_token_role( let mut token = contract.tokens.load(deps.storage, &token_id)?; // Update role with new value - token.extension.role = role.clone(); + token.extension.role.clone_from(&role); contract.tokens.save(deps.storage, &token_id, &token)?; Ok(Response::default() @@ -341,7 +341,7 @@ pub fn execute_update_token_uri( let mut token = contract.tokens.load(deps.storage, &token_id)?; // Set new token URI - token.token_uri = token_uri.clone(); + token.token_uri.clone_from(&token_uri); contract.tokens.save(deps.storage, &token_id, &token)?; Ok(Response::new() diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index ff3827b82..a347bf3f2 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-proposal-incentives" -authors = ["Jake Hartnell ", "ismellike"] +authors = ["Jake Hartnell ", "Gabe Lopez "] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } diff --git a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json index 2d02b5883..a258c15ea 100644 --- a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json +++ b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-proposal-incentives", - "contract_version": "2.4.0", + "contract_version": "2.4.2", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 2adca6808..903ef94df 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -357,6 +357,7 @@ pub fn test_hook() { funds: vec![], })], proposer: None, + vote: None, }), &[], ); @@ -390,6 +391,7 @@ pub fn test_hook() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) @@ -418,6 +420,7 @@ pub fn test_hook() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index be6d63c19..882d4a7ab 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-voting-incentives" -authors = ["Jake Hartnell ", "ismellike"] +authors = ["Jake Hartnell ", "Gabe Lopez "] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index f2331d18e..08eefdf57 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-voting-incentives", - "contract_version": "2.4.0", + "contract_version": "2.4.2", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index d4058e61f..a6fb3ebb6 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -319,6 +319,7 @@ pub fn test_hooks() { }), ], proposer: None, + vote: None, }), &[], ); @@ -358,6 +359,7 @@ pub fn test_hooks() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) @@ -435,6 +437,7 @@ pub fn test_hooks() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) diff --git a/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json b/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json index 1ffbbb163..ef9e647a1 100644 --- a/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json +++ b/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json @@ -1140,6 +1140,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -1256,6 +1280,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "info": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "InfoResponse", diff --git a/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json b/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json index 415412ea2..2b95657b5 100644 --- a/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json +++ b/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json @@ -2078,6 +2078,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -2580,6 +2604,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "get_vote": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "VoteResponse", diff --git a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json index 2491d27aa..566cc760d 100644 --- a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json +++ b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json @@ -2156,6 +2156,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -2711,6 +2735,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "get_vote": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "VoteResponse", From 064f3536f1a14b973988805769702be7032e80ba Mon Sep 17 00:00:00 2001 From: ismellike Date: Thu, 13 Jun 2024 10:24:30 -0500 Subject: [PATCH 21/47] Update contracts/external/dao-proposal-incentives/Cargo.toml Co-authored-by: Jake Hartnell --- contracts/external/dao-proposal-incentives/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index a347bf3f2..73ba15581 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="dao-proposal-incentives" authors = ["Jake Hartnell ", "Gabe Lopez "] -description = "A contract that implements incentives for voting in a DAO." +description = "A contract that implements incentives for creating a successful proposal in a DAO." edition = { workspace = true } license = { workspace = true } repository = { workspace = true } From 8849221183043fff28b744547a44f3b64afa3b21 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Tue, 9 Jan 2024 00:34:41 -0800 Subject: [PATCH 22/47] Smart contract skeleton for voting incentives --- Cargo.lock | 347 +++++++++--------- .../dao-voting-incentives/.cargo/config | 4 + .../external/dao-voting-incentives/Cargo.toml | 33 ++ .../external/dao-voting-incentives/README.md | 14 + .../dao-voting-incentives/examples/schema.rs | 11 + .../schema/cw-admin-factory.json | 69 ++++ .../dao-voting-incentives/src/contract.rs | 80 ++++ .../dao-voting-incentives/src/error.rs | 18 + .../external/dao-voting-incentives/src/lib.rs | 10 + .../external/dao-voting-incentives/src/msg.rs | 27 ++ .../dao-voting-incentives/src/tests.rs | 168 +++++++++ 11 files changed, 604 insertions(+), 177 deletions(-) create mode 100644 contracts/external/dao-voting-incentives/.cargo/config create mode 100644 contracts/external/dao-voting-incentives/Cargo.toml create mode 100644 contracts/external/dao-voting-incentives/README.md create mode 100644 contracts/external/dao-voting-incentives/examples/schema.rs create mode 100644 contracts/external/dao-voting-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-voting-incentives/src/contract.rs create mode 100644 contracts/external/dao-voting-incentives/src/error.rs create mode 100644 contracts/external/dao-voting-incentives/src/lib.rs create mode 100644 contracts/external/dao-voting-incentives/src/msg.rs create mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index b1e7d67d1..9d86eb39d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -79,7 +79,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -203,7 +203,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.72", + "syn 2.0.74", "which", ] @@ -333,18 +333,21 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.1.6" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -418,9 +421,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cosm-orc" @@ -533,32 +536,31 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" dependencies = [ "digest 0.10.7", - "ecdsa 0.16.9", "ed25519-zebra", - "k256 0.13.1", + "k256 0.13.3", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7879036156092ad1c22fe0d7316efc5a5eceec2bc3906462a2560215f2a2f929" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -569,9 +571,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" dependencies = [ "proc-macro2", "quote", @@ -580,9 +582,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.5" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" dependencies = [ "base64 0.21.7", "bech32", @@ -612,9 +614,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -2461,6 +2463,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "dao-voting-incentives" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + [[package]] name = "dao-voting-onft-staked" version = "2.5.0" @@ -2846,7 +2865,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -2949,7 +2968,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.6", + "indexmap 2.4.0", "slab", "tokio", "tokio-util", @@ -3001,6 +3020,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -3179,9 +3204,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -3223,11 +3248,11 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] @@ -3241,6 +3266,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -3258,9 +3292,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -3291,9 +3325,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa 0.16.9", @@ -3326,9 +3360,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.156" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" [[package]] name = "libloading" @@ -3337,7 +3371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3393,13 +3427,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3432,16 +3467,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -3453,9 +3478,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.1" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -3655,7 +3680,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -3686,7 +3711,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -3723,9 +3748,12 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" @@ -3734,7 +3762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -3798,10 +3826,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -3869,9 +3897,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -4074,7 +4102,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4146,9 +4174,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] @@ -4182,13 +4210,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4199,16 +4227,17 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4221,7 +4250,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4230,7 +4259,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "itoa", "ryu", "serde", @@ -4445,9 +4474,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", @@ -4698,7 +4727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" dependencies = [ "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4734,7 +4763,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4771,19 +4800,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4798,13 +4826,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -4933,15 +4961,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -4962,7 +4990,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] [[package]] @@ -5054,9 +5082,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vote-hooks" @@ -5097,34 +5125,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5132,28 +5161,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -5208,11 +5237,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5221,37 +5250,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -5260,46 +5274,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -5312,48 +5308,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -5381,6 +5353,27 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -5398,5 +5391,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.74", ] diff --git a/contracts/external/dao-voting-incentives/.cargo/config b/contracts/external/dao-voting-incentives/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/external/dao-voting-incentives/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml new file mode 100644 index 000000000..97106c68a --- /dev/null +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name ="dao-voting-incentives" +authors = ["Jake Hartnell "] +description = "A contract that implements incentives for voting in a DAO." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +dao-hooks = { workspace = true } +dao-interface = { workspace = true } +thiserror = { workspace = true } +cw-utils = { workspace = true } + +[dev-dependencies] +cosmwasm-schema = { workspace = true } +cw-multi-test = { workspace = true } +dao-dao-core = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md new file mode 100644 index 000000000..2ee2a1d98 --- /dev/null +++ b/contracts/external/dao-voting-incentives/README.md @@ -0,0 +1,14 @@ +# cw-admin-factory + +[![cw-admin-factory on crates.io](https://img.shields.io/crates/v/cw-admin-factory.svg?logo=rust)](https://crates.io/crates/cw-admin-factory) +[![docs.rs](https://img.shields.io/docsrs/cw-admin-factory?logo=docsdotrs)](https://docs.rs/cw-admin-factory/latest/cw_admin_factory/) + +Serves as a factory that instantiates contracts and sets them as their +own wasm admins. + +Useful for allowing contracts (e.g. DAOs) to migrate themselves. + +Example instantiation flow: + +![](https://bafkreibqsrdnht5chc5mdzbb6pgiyqfjke3yvukvjrokyefwwbl3k3iwaa.ipfs.nftstorage.link) + diff --git a/contracts/external/dao-voting-incentives/examples/schema.rs b/contracts/external/dao-voting-incentives/examples/schema.rs new file mode 100644 index 000000000..52981727a --- /dev/null +++ b/contracts/external/dao-voting-incentives/examples/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; +use dao_voting_incentives::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json new file mode 100644 index 000000000..f1a1e1254 --- /dev/null +++ b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json @@ -0,0 +1,69 @@ +{ + "contract_name": "cw-admin-factory", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", + "type": "object", + "required": [ + "instantiate_contract_with_self_admin" + ], + "properties": { + "instantiate_contract_with_self_admin": { + "type": "object", + "required": [ + "code_id", + "instantiate_msg", + "label" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "instantiate_msg": { + "$ref": "#/definitions/Binary" + }, + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "type": "string", + "enum": [] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": {} +} diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs new file mode 100644 index 000000000..5ec59d86d --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -0,0 +1,80 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cw2::set_contract_version; +use dao_hooks::vote::VoteHookMsg; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const INSTANTIATE_CONTRACT_REPLY_ID: u64 = 0; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + // Save config + + // Check initial deposit + + Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("creator", info.sender)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Claim {} => unimplemented!(), + ExecuteMsg::VoteHook(msg) => unimplemented!(), + } +} + +pub fn execute_claim( + deps: DepsMut, + env: Env, + info: MessageInfo, +) -> Result { + Ok(Response::default().add_attribute("action", "claim")) +} + +pub fn execute_vote_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: VoteHookMsg, +) -> Result { + // Check epoch + + // TODO what is the best data structure to use here? + // Save vote + // Save prop ID + + Ok(Response::default().add_attribute("action", "vote_hook")) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Rewards { address } => unimplemented!(), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs new file mode 100644 index 000000000..56c764778 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::StdError; +use cw_utils::ParseReplyError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("{0}")] + ParseReplyError(#[from] ParseReplyError), + + #[error("An unknown reply ID was received.")] + UnknownReplyID {}, +} diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs new file mode 100644 index 000000000..6902586b6 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -0,0 +1,10 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +pub mod contract; +mod error; +pub mod msg; + +#[cfg(test)] +mod tests; + +pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs new file mode 100644 index 000000000..a002932b5 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -0,0 +1,27 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use dao_hooks::vote::VoteHookMsg; + +#[cw_serde] +pub struct InstantiateMsg { + /// DAO address + pub dao: String, +} + +#[cw_serde] +pub enum ExecuteMsg { + /// Fires when a new vote is cast. + VoteHook(VoteHookMsg), + /// Claim rewards. + Claim {}, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Returns the rewards for the given address. + #[returns(cosmwasm_std::Uint128)] + Rewards { address: String }, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs new file mode 100644 index 000000000..3bee180ee --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -0,0 +1,168 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, +}; + +use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use dao_interface::state::{Admin, ModuleInstantiateInfo}; + +use crate::{ + contract::instantiate, + contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, +}; + +fn factory_contract() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ) + .with_reply(crate::contract::reply); + Box::new(contract) +} + +fn cw20_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) +} + +fn cw_core_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core::contract::execute, + dao_dao_core::contract::instantiate, + dao_dao_core::contract::query, + ) + .with_reply(dao_dao_core::contract::reply) + .with_migrate(dao_dao_core::contract::migrate); + Box::new(contract) +} + +#[test] +pub fn test_set_admin() { + let mut app = App::default(); + let code_id = app.store_code(factory_contract()); + let cw20_code_id = app.store_code(cw20_contract()); + let cw20_instantiate = cw20_base::msg::InstantiateMsg { + name: "DAO".to_string(), + symbol: "DAO".to_string(), + decimals: 6, + initial_balances: vec![], + mint: None, + marketing: None, + }; + + let instantiate = InstantiateMsg {}; + let factory_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("CREATOR"), + &instantiate, + &[], + "cw-admin-factory", + None, + ) + .unwrap(); + + // Instantiate core contract using factory. + let cw_core_code_id = app.store_code(cw_core_contract()); + let instantiate_core = dao_interface::msg::InstantiateMsg { + dao_uri: None, + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that builds DAOs.".to_string(), + image_url: None, + automatically_add_cw20s: true, + automatically_add_cw721s: true, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "voting module".to_string(), + }, + proposal_modules_instantiate_info: vec![ + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module".to_string(), + }, + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module 2".to_string(), + }, + ], + initial_items: None, + }; + + let res: AppResponse = app + .execute_contract( + Addr::unchecked("CREATOR"), + factory_addr, + &ExecuteMsg::InstantiateContractWithSelfAdmin { + instantiate_msg: to_json_binary(&instantiate_core).unwrap(), + code_id: cw_core_code_id, + label: "my contract".to_string(), + }, + &[], + ) + .unwrap(); + + // Get the core address from the instantiate event + let instantiate_event = &res.events[2]; + assert_eq!(instantiate_event.ty, "instantiate"); + let core_addr = instantiate_event.attributes[0].value.clone(); + + // Check that admin of core address is itself + let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); + assert_eq!(contract_info.admin, Some(core_addr)) +} + +#[test] +pub fn test_set_admin_mock() { + let mut deps = mock_dependencies(); + // Instantiate factory contract + let instantiate_msg = InstantiateMsg {}; + let info = mock_info("creator", &[]); + let env = mock_env(); + instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); + let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; + let reply_msg: Reply = Reply { + id: INSTANTIATE_CONTRACT_REPLY_ID, + result: SubMsgResult::Ok(SubMsgResponse { + events: vec![], + data: (Some(Binary(bytes))), + }), + }; + + let res = reply(deps.as_mut(), env, reply_msg).unwrap(); + assert_eq!(res.attributes.len(), 1); + assert_eq!( + res.messages[0], + SubMsg::new(WasmMsg::UpdateAdmin { + contract_addr: "contract2".to_string(), + admin: "contract2".to_string() + }) + ) +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} From 55b966535bfd5503c7f1973a541bcf5a98180288 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Mon, 22 Jan 2024 17:20:35 -0800 Subject: [PATCH 23/47] More comments --- .../external/dao-voting-incentives/src/contract.rs | 10 +++++----- contracts/external/dao-voting-incentives/src/msg.rs | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 5ec59d86d..6f10d0d09 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -9,7 +9,6 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub const INSTANTIATE_CONTRACT_REPLY_ID: u64 = 0; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -37,8 +36,8 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Claim {} => unimplemented!(), - ExecuteMsg::VoteHook(msg) => unimplemented!(), + ExecuteMsg::Claim {} => execute_claim(deps, env, info), + ExecuteMsg::VoteHook(msg) => execute_vote_hook(deps, env, info, msg), } } @@ -59,8 +58,9 @@ pub fn execute_vote_hook( // Check epoch // TODO what is the best data structure to use here? - // Save vote - // Save prop ID + // Save vote? Save prop ID? + // Save (user, epoch, vote count) + // Save (epoch, prop count) Ok(Response::default().add_attribute("action", "vote_hook")) } diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index a002932b5..67642be33 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,10 +1,13 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Timestamp; use dao_hooks::vote::VoteHookMsg; #[cw_serde] pub struct InstantiateMsg { /// DAO address pub dao: String, + /// Epoch duration in seconds. Used for reward calculation. + pub epoch_duration: Timestamp, } #[cw_serde] From aa3dd76344b1158170ec4b23605a8edd536630c3 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Wed, 24 Jan 2024 16:23:07 +0100 Subject: [PATCH 24/47] dao-proposal-incentives initial commit --- .../dao-proposal-incentives/.cargo/config | 4 + .../dao-proposal-incentives/Cargo.toml | 34 ++++ .../dao-proposal-incentives/README.md | 6 + .../examples/schema.rs | 11 ++ .../schema/cw-admin-factory.json | 69 +++++++ .../dao-proposal-incentives/src/contract.rs | 126 +++++++++++++ .../dao-proposal-incentives/src/error.rs | 18 ++ .../dao-proposal-incentives/src/lib.rs | 11 ++ .../dao-proposal-incentives/src/msg.rs | 37 ++++ .../dao-proposal-incentives/src/state.rs | 16 ++ .../dao-proposal-incentives/src/tests.rs | 168 ++++++++++++++++++ 11 files changed, 500 insertions(+) create mode 100644 contracts/external/dao-proposal-incentives/.cargo/config create mode 100644 contracts/external/dao-proposal-incentives/Cargo.toml create mode 100644 contracts/external/dao-proposal-incentives/README.md create mode 100644 contracts/external/dao-proposal-incentives/examples/schema.rs create mode 100644 contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-proposal-incentives/src/contract.rs create mode 100644 contracts/external/dao-proposal-incentives/src/error.rs create mode 100644 contracts/external/dao-proposal-incentives/src/lib.rs create mode 100644 contracts/external/dao-proposal-incentives/src/msg.rs create mode 100644 contracts/external/dao-proposal-incentives/src/state.rs create mode 100644 contracts/external/dao-proposal-incentives/src/tests.rs diff --git a/contracts/external/dao-proposal-incentives/.cargo/config b/contracts/external/dao-proposal-incentives/.cargo/config new file mode 100644 index 000000000..336b618a1 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml new file mode 100644 index 000000000..4de53d38c --- /dev/null +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name ="dao-proposal-incentives" +authors = ["Jake Hartnell "] +description = "A contract that implements incentives for voting in a DAO." +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +dao-hooks = { workspace = true } +dao-interface = { workspace = true } +dao-voting = { workspace = true } +thiserror = { workspace = true } +cw-utils = { workspace = true } + +[dev-dependencies] +cosmwasm-schema = { workspace = true } +cw-multi-test = { workspace = true } +dao-dao-core = { workspace = true, features = ["library"] } +cw20-base = { workspace = true, features = ["library"] } diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md new file mode 100644 index 000000000..20a0f9ff4 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/README.md @@ -0,0 +1,6 @@ +# dao-proposal-incentives + +[![dao-proposal-incentives on crates.io](https://img.shields.io/crates/v/dao-proposal-incentives.svg?logo=rust)](https://crates.io/crates/dao-proposal-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) + +Allows for DAOs to offer incentives for making successful proposals. diff --git a/contracts/external/dao-proposal-incentives/examples/schema.rs b/contracts/external/dao-proposal-incentives/examples/schema.rs new file mode 100644 index 000000000..faa86b601 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/examples/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; +use dao_proposal_incentives::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json new file mode 100644 index 000000000..f1a1e1254 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json @@ -0,0 +1,69 @@ +{ + "contract_name": "cw-admin-factory", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", + "type": "object", + "required": [ + "instantiate_contract_with_self_admin" + ], + "properties": { + "instantiate_contract_with_self_admin": { + "type": "object", + "required": [ + "code_id", + "instantiate_msg", + "label" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "instantiate_msg": { + "$ref": "#/definitions/Binary" + }, + "label": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "type": "string", + "enum": [] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": {} +} diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs new file mode 100644 index 000000000..8e01dacb3 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -0,0 +1,126 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + SubMsg, +}; +use cw2::set_contract_version; +use dao_hooks::proposal::ProposalHookMsg; +use dao_voting::status::Status; + +use crate::error::ContractError; +use crate::msg::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::{DAO, PROPOSAL_INCENTIVES}; + +pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub const REPLY_PROPOSAL_HOOK_ID: u64 = 1; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + // Save DAO, assumes the sender is the DAO + DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + + // Save proposal incentives config + PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; + + // TODO Check initial deposit contains enough funds to pay out rewards + // for at least one proposal + + Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("creator", info.sender)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::ProposalHook(msg) => execute_proposal_hook(deps, env, info, msg), + } +} + +// TODO support cw20 tokens +pub fn execute_proposal_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ProposalHookMsg, +) -> Result { + let mut payout_msgs: Vec = vec![]; + + // Check prop status and type of hook + match msg { + ProposalHookMsg::ProposalStatusChanged { new_status, .. } => { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; + + // We handle payout messages in a SubMsg so the error be caught + // if need be. This is to prevent running out of funds locking the DAO. + payout_msgs.push(SubMsg::reply_on_error( + BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![proposal_incentives.rewards_per_proposal], + }, + REPLY_PROPOSAL_HOOK_ID, + )); + } + } + _ => {} + } + + Ok(Response::default() + .add_attribute("action", "proposal_hook") + .add_submessages(payout_msgs)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Config {} => query_config(deps), + } +} + +pub fn query_config(deps: Deps) -> StdResult { + let dao = DAO.load(deps.storage)?; + let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; + + to_json_binary(&ConfigResponse { + dao, + proposal_incentives, + }) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // Set contract to version to latest + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { + match msg.id { + REPLY_PROPOSAL_HOOK_ID => { + // If an error occurred with payout, we still return an ok response + // because we don't want to fail the proposal hook and lock the DAO. + Ok(Response::default()) + } + _ => Err(ContractError::UnknownReplyID {}), + } +} diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs new file mode 100644 index 000000000..56c764778 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::StdError; +use cw_utils::ParseReplyError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("{0}")] + ParseReplyError(#[from] ParseReplyError), + + #[error("An unknown reply ID was received.")] + UnknownReplyID {}, +} diff --git a/contracts/external/dao-proposal-incentives/src/lib.rs b/contracts/external/dao-proposal-incentives/src/lib.rs new file mode 100644 index 000000000..d1800adbc --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/lib.rs @@ -0,0 +1,11 @@ +#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] + +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +#[cfg(test)] +mod tests; + +pub use crate::error::ContractError; diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs new file mode 100644 index 000000000..0c714bcce --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -0,0 +1,37 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use dao_hooks::{proposal::ProposalHookMsg, vote::VoteHookMsg}; + +use crate::state::{ProposalIncentives, VotingIncentives}; + +#[cw_serde] +pub struct InstantiateMsg { + /// DAO address + pub dao: String, + /// Rewards to pay out for successful proposals. + pub proposal_incentives: ProposalIncentives, +} + +#[cw_serde] +pub enum ExecuteMsg { + /// Fires when a new proposal status has changed. + ProposalHook(ProposalHookMsg), +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Returns the config. + #[returns(ConfigResponse)] + Config {}, +} + +#[cw_serde] +pub struct ConfigResponse { + /// DAO address + pub dao: String, + /// Rewards to pay out for successful proposals. + pub proposal_incentives: ProposalIncentives, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/contracts/external/dao-proposal-incentives/src/state.rs b/contracts/external/dao-proposal-incentives/src/state.rs new file mode 100644 index 000000000..ee7c7c0af --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/state.rs @@ -0,0 +1,16 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin}; +use cw_storage_plus::Item; + +/// The address of the DAO this contract serves +pub const DAO: Item = Item::new("dao"); + +/// Incentives for passing successful proposals +#[cw_serde] +pub struct ProposalIncentives { + /// The rewards to pay out per successful proposal. + pub rewards_per_proposal: Coin, +} + +/// Holds ProposalIncentives state +pub const PROPOSAL_INCENTIVES: Item = Item::new("proposal_incentives"); diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs new file mode 100644 index 000000000..3bee180ee --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -0,0 +1,168 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, +}; + +use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use dao_interface::state::{Admin, ModuleInstantiateInfo}; + +use crate::{ + contract::instantiate, + contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, +}; + +fn factory_contract() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ) + .with_reply(crate::contract::reply); + Box::new(contract) +} + +fn cw20_contract() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) +} + +fn cw_core_contract() -> Box> { + let contract = ContractWrapper::new( + dao_dao_core::contract::execute, + dao_dao_core::contract::instantiate, + dao_dao_core::contract::query, + ) + .with_reply(dao_dao_core::contract::reply) + .with_migrate(dao_dao_core::contract::migrate); + Box::new(contract) +} + +#[test] +pub fn test_set_admin() { + let mut app = App::default(); + let code_id = app.store_code(factory_contract()); + let cw20_code_id = app.store_code(cw20_contract()); + let cw20_instantiate = cw20_base::msg::InstantiateMsg { + name: "DAO".to_string(), + symbol: "DAO".to_string(), + decimals: 6, + initial_balances: vec![], + mint: None, + marketing: None, + }; + + let instantiate = InstantiateMsg {}; + let factory_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("CREATOR"), + &instantiate, + &[], + "cw-admin-factory", + None, + ) + .unwrap(); + + // Instantiate core contract using factory. + let cw_core_code_id = app.store_code(cw_core_contract()); + let instantiate_core = dao_interface::msg::InstantiateMsg { + dao_uri: None, + admin: None, + name: "DAO DAO".to_string(), + description: "A DAO that builds DAOs.".to_string(), + image_url: None, + automatically_add_cw20s: true, + automatically_add_cw721s: true, + voting_module_instantiate_info: ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "voting module".to_string(), + }, + proposal_modules_instantiate_info: vec![ + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module".to_string(), + }, + ModuleInstantiateInfo { + code_id: cw20_code_id, + msg: to_json_binary(&cw20_instantiate).unwrap(), + admin: Some(Admin::CoreModule {}), + funds: vec![], + label: "prop module 2".to_string(), + }, + ], + initial_items: None, + }; + + let res: AppResponse = app + .execute_contract( + Addr::unchecked("CREATOR"), + factory_addr, + &ExecuteMsg::InstantiateContractWithSelfAdmin { + instantiate_msg: to_json_binary(&instantiate_core).unwrap(), + code_id: cw_core_code_id, + label: "my contract".to_string(), + }, + &[], + ) + .unwrap(); + + // Get the core address from the instantiate event + let instantiate_event = &res.events[2]; + assert_eq!(instantiate_event.ty, "instantiate"); + let core_addr = instantiate_event.attributes[0].value.clone(); + + // Check that admin of core address is itself + let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); + assert_eq!(contract_info.admin, Some(core_addr)) +} + +#[test] +pub fn test_set_admin_mock() { + let mut deps = mock_dependencies(); + // Instantiate factory contract + let instantiate_msg = InstantiateMsg {}; + let info = mock_info("creator", &[]); + let env = mock_env(); + instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); + let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; + let reply_msg: Reply = Reply { + id: INSTANTIATE_CONTRACT_REPLY_ID, + result: SubMsgResult::Ok(SubMsgResponse { + events: vec![], + data: (Some(Binary(bytes))), + }), + }; + + let res = reply(deps.as_mut(), env, reply_msg).unwrap(); + assert_eq!(res.attributes.len(), 1); + assert_eq!( + res.messages[0], + SubMsg::new(WasmMsg::UpdateAdmin { + contract_addr: "contract2".to_string(), + admin: "contract2".to_string() + }) + ) +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} From e219dea97963358cb46a42ef3010d91d959c1c78 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Wed, 24 Jan 2024 16:29:13 +0100 Subject: [PATCH 25/47] Add more design notes and TODOs --- Cargo.lock | 10827 ++++++++-------- .../external/dao-voting-incentives/Cargo.toml | 1 + .../dao-voting-incentives/src/contract.rs | 45 +- .../external/dao-voting-incentives/src/lib.rs | 1 + .../external/dao-voting-incentives/src/msg.rs | 18 +- .../dao-voting-incentives/src/state.rs | 33 + 6 files changed, 5518 insertions(+), 5407 deletions(-) create mode 100644 contracts/external/dao-voting-incentives/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index 9d86eb39d..63f0aba9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5395 +1,5432 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "async-trait" -version = "0.1.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -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 = "bindgen" -version = "0.68.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.74", - "which", -] - -[[package]] -name = "bip32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" -dependencies = [ - "bs58", - "hmac", - "k256 0.11.6", - "once_cell", - "pbkdf2", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" - -[[package]] -name = "bootstrap-env" -version = "0.2.0" -dependencies = [ - "anyhow", - "cosm-orc", - "cosmwasm-std", - "cw-admin-factory", - "cw-utils 1.0.3", - "cw20 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "env_logger", - "serde", - "serde_json", - "serde_yaml", -] - -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -dependencies = [ - "sha2 0.9.9", -] - -[[package]] -name = "btsg-ft-factory" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-token-staked", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" -dependencies = [ - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "num-traits", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "config" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" -dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml", - "yaml-rust", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cosm-orc" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6676a17fddc94aac5fe07bad646d99b7f7cef1f0cc2c74b61af25733cbbb9f08" -dependencies = [ - "config", - "cosm-tome", - "erased-serde", - "log", - "serde", - "serde_json", - "thiserror", - "tokio", -] - -[[package]] -name = "cosm-tome" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "596064e3608349aa302eb68b2df8ed3a66bbb51d9b470dbd9afff70843e44642" -dependencies = [ - "async-trait", - "cosmrs 0.10.0", - "regex", - "schemars", - "serde", - "serde_json", - "thiserror", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b42021d8488665b1a0d9748f1f81df7235362d194f44481e2e61bf376b77b4" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.23.9", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673d31bd830c0772d78545de20d975129b6ab2f7db4e4e9313c3b8777d319194" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.26.0", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.32.2", - "tonic 0.9.2", -] - -[[package]] -name = "cosmrs" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3903590099dcf1ea580d9353034c9ba1dbf55d1389a5bd2ade98535c3445d1f9" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.14.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-rpc 0.23.9", - "thiserror", -] - -[[package]] -name = "cosmrs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa07096219b1817432b8f1e47c22e928c64bbfd231fc08f0a98f0e7ddd602b7" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.15.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-rpc 0.26.0", - "thiserror", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" -dependencies = [ - "digest 0.10.7", - "ed25519-zebra", - "k256 0.13.3", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-std" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" -dependencies = [ - "base64 0.21.7", - "bech32", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.8", - "static_assertions", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-address-like" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" -dependencies = [ - "cosmwasm-std", -] - -[[package]] -name = "cw-admin-factory" -version = "2.5.0" -dependencies = [ - "bech32", - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "osmosis-test-tube", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bfeaf55f8dba5646cc3daddce17cd23a60f8e0c3fbacbe6735d287d7a6e33a" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468b8f2696f625c8e15b5468f9420c8eabfaf23cb4fd7e6c660fc7e0cc8d77b8" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-paginate-storage 0.1.0", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw721 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c93e684945473777ebed2bcaf9f0af2291653f79d5c81774c6826350ba6d88de" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20a77489d2dc8a1c12cb0b9671b6cbdca88f12fe65e1a4ee9899490f7669dcc" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "proc-macro2", - "quote", - "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" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-fund-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-voting-cw20-staked", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "097ee97b99ecc90372eac3bcaf698d940a15f806f2ba1e1e901c729f6523e16e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" -dependencies = [ - "anyhow", - "bech32", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "derivative", - "itertools 0.12.1", - "prost 0.12.3", - "schemars", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-ownable" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw-ownable-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-paginate-storage" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b854833e07c557dee02d1b61a21bb0731743bb2e3bbdc3e446a0d8a38af40ec4" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9740c02c59072ad00de64cc60aae6ca492103dcefc0f7d3cc6f77d768f2ec70" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.5.0" -dependencies = [ - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-payroll-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-proposal-single" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6408483e1ac17a7e2b98ef6fa1379776964353bcbf501942d22ee1c1323117" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw3", - "dao-voting 0.1.0", - "indexable-hooks", - "proposal-hooks", - "schemars", - "serde", - "thiserror", - "vote-hooks", -] - -[[package]] -name = "cw-stake-tracker" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-wormhole", -] - -[[package]] -name = "cw-storage-plus" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-token-swap" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-issuer" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-types", - "cw2 1.1.2", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-types" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "cw-utils" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef842a1792e4285beff7b3b518705f760fa4111dc1e296e53f3e92d1ef7f6220" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 0.16.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-vesting" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-stake-tracker", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-wormhole", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-testing", - "serde", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-wormhole" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw2" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9671d7edef5608acaf5b2f1e473ee3f501eced2cd4f7392e2106c8cf02ba0720" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f6fc8c4cd451b418fa4f1ac2ea70595811fa9d8b4033617fe47953d7a93ceb" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f0d51ce27a97b51f66d737183845bc6d82f46f4b246dc959d1265d86906ccc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "dao-hooks 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "cw20-stake-external-rewards" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-hooks 2.5.0", - "stake-cw20-external-rewards", - "thiserror", -] - -[[package]] -name = "cw20-stake-reward-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "stake-cw20-reward-distributor", - "thiserror", -] - -[[package]] -name = "cw20-staked-balance-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf8c2ee92372d35c3a48fd6ddd490a1a4426902748017dd0b7f551d06484e28" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw3" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", -] - -[[package]] -name = "cw4-group" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6c95c89153e7831c8306c8eba40a3daa76f9c7b8f5179dd0b8628aca168ec7a" -dependencies = [ - "cosmwasm-std", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-group" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-voting" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "cw4-group 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035818368a74c07dd9ed5c5a93340199ba251530162010b9f34c3809e3b97df1" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw721-base" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "cw-utils 0.16.0", - "cw2 0.16.0", - "cw721 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-base" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-controllers" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw721-roles" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-cw721-extensions", - "dao-testing", - "dao-voting-cw721-staked", - "serde", - "thiserror", -] - -[[package]] -name = "dao-cw721-extensions" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw4 1.1.2", -] - -[[package]] -name = "dao-dao-core" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd16c5f6f2760c66546e1e2f3781106dd796c8920847e78e5984922767cbc68" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw721 0.18.0", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-dao-core" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c3f39b7aaf9d913d0de8c8742c151011da00662acdbe95c33a5f7bad1b835a" -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 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dao-hooks" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c85abbadefe491d571f709464a8cfd2fb78b63b0cb6e6ef49104df249e28acc" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw4 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw4 1.1.2", - "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" -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-migrator" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-multi-test", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "cw20-stake 2.5.0", - "cw20-staked-balance-voting", - "cw4 0.13.4", - "cw4-voting", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4fe4e5b50b3081272557069dbecaf1e0984d1f2932d2e61418712460f8fd313" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.4.1", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approver" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", -] - -[[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.2", - "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 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 2.5.0", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6158aeddd2e080c730f1a2ac3814351cbcd38d61c38209dcf1e203d0e554a5" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.4.1", - "dao-proposal-multiple 2.4.1", - "dao-proposal-multiple 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f96fb1898f94ea4fe5771f8ab5c2bc6237782e06bb599f070713d11d38c19e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.4.1", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-proposal-condorcet" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-proposal-hook-counter" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fac47816150063ef09b555f3466f8be99612b76860a20fba7c85bd1854beba" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-pre-propose-multiple 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "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", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "rand", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce91710cfcff1af520cd0e885eee6972aeefbefc1c9da18349e66ab959269bb" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "thiserror", -] - -[[package]] -name = "dao-proposal-sudo" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-rewards-distributor" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "semver", - "thiserror", -] - -[[package]] -name = "dao-test-custom-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-testing" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-core", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-proposal-single", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-condorcet", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-roles", - "dao-voting-cw721-staked", - "dao-voting-onft-staked", - "dao-voting-token-staked", - "osmosis-std", - "osmosis-test-tube", - "rand", - "serde", - "serde_json", - "stake-cw20", -] - -[[package]] -name = "dao-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442d770933e3b3ecab4cfb4d6e9d054082b007d35fda3cf0c3d3ddd1cfa91782" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "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.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw20 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-balance" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-staked" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba59e19abd4d51d6c3a37a84fb0c8cfe90e2f2ab551a610ec6749fcd09fc9e86" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-roles" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "cw721-roles", - "dao-cw721-extensions", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-incentives" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-onft-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "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 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "omniflix-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-token-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "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 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der 0.7.9", - "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", -] - -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek", - "ed25519", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", - "digest 0.10.7", - "ff 0.13.0", - "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1 0.7.3", - "subtle", - "zeroize", -] - -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.0", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.4.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "hyper-rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "tower-service", - "webpki", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "webpki", - "webpki-roots", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexable-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d70922e1e0e68d99ec1a24446c70756cc3e56deaddb505b1f4b43914522d809" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "integration-tests" -version = "0.1.0" -dependencies = [ - "anyhow", - "assert_matches", - "cosm-orc", - "cosm-tome", - "cosmos-sdk-proto 0.19.0", - "cosmwasm-std", - "cw-utils 1.0.3", - "cw-vesting", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw721-staked", - "env_logger", - "once_cell", - "rand", - "serde", - "serde_json", - "test-context", -] - -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", - "sha3", -] - -[[package]] -name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" -dependencies = [ - "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", - "once_cell", - "sha2 0.10.8", - "signature 2.2.0", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.156" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" - -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.36.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" -dependencies = [ - "memchr", -] - -[[package]] -name = "omniflix-std" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a662bd7782ef6ad1af3747a2b73d37f8e6a230bb7b1624d96c05b3567501600" -dependencies = [ - "chrono", - "cosmwasm-std", - "omniflix-std-derive", - "prost 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "omniflix-std-derive" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbd85582e3ef1a23fa7b12e0415ea604260c114e72faf40d829c2c40f1c745e" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "osmosis-std" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d7aa053bc3fad557ac90a0377688b400c395e2537f0f1de3293a15cad2e970" -dependencies = [ - "chrono", - "cosmwasm-std", - "osmosis-std-derive", - "prost 0.11.9", - "prost-types 0.11.9", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "osmosis-std-derive" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "osmosis-test-tube" -version = "20.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" -dependencies = [ - "base64 0.21.7", - "bindgen", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "test-tube", - "thiserror", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "pest_meta" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" -dependencies = [ - "once_cell", - "pest", - "sha2 0.10.8", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.9", - "spki 0.7.3", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" -dependencies = [ - "proc-macro2", - "syn 2.0.74", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proposal-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a2f15b848398bad689771b35313c7e7095e772d444e299dbdb54b906691f8a" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" -dependencies = [ - "bytes", - "prost-derive 0.12.3", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-derive" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" -dependencies = [ - "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - -[[package]] -name = "prost-types" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" -dependencies = [ - "prost 0.12.3", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "serde", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls", - "schannel", - "security-framework", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.74", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.9", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-cw-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_json" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.4.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.9", -] - -[[package]] -name = "stake-cw20" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfbd45133276dbe4d6588899f4d4d06fdb9f16921fd1394affc0bccc9a5cb0b6" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.11.1", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "cw20-base 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-external-rewards" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9bbc1e4b7a932957a05a76921015a849b234c3f25e59fe1fd0d2eab71654bc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-reward-distributor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4260ff7aec6dddb43cb5f1104ef5cebe2787853bc83af9172ce5b828b577c4c5" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "tendermint" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467f82178deeebcd357e1273a0c0b77b9a8a0313ef7c07074baebe99d87851f4" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.23.9", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.26.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42ee0abc27ef5fc34080cce8d43c189950d331631546e7dfb983b6274fa327" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.23.9", - "toml", - "url", -] - -[[package]] -name = "tendermint-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202a2f19502c03b353d8157694ed24fbc58c3dd64a92a5b0cb80b79c82af5be4" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.26.0", - "toml", - "url", -] - -[[package]] -name = "tendermint-proto" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ce80bf536476db81ecc9ebab834dc329c9c1509a694f211a73858814bfe023" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974d6330a19dfa6720e9f663fc59101d207a817db3f9c730d3f31caaa565b574" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f14aafe3528a0f75e9f3f410b525617b2de16c4b7830a21f717eee62882ec60" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-config 0.23.9", - "tendermint-proto 0.23.9", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tendermint-rpc" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d87fa5429bd2ee39c4809dd546096daf432de9b71157bc12c182ab5bae7ea7" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-config 0.26.0", - "tendermint-proto 0.26.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test-context" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6965c21232186af0092233c18030fe607cfc3960dbabb209325272458eeea" -dependencies = [ - "async-trait", - "futures", - "test-context-macros", -] - -[[package]] -name = "test-context-macros" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" -dependencies = [ - "quote", - "syn 2.0.74", -] - -[[package]] -name = "test-tube" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e79c7af10967dd3383ee5aae3810637cc3f2fd040f87f862c02151db060628" -dependencies = [ - "base64 0.13.1", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "time" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" -dependencies = [ - "libc", - "num_threads", - "time-macros", -] - -[[package]] -name = "time-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.39.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "tonic" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.13.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "prost-derive 0.11.9", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vote-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef617ad17edd195f8a3bce72498bfcc406a27cecfc23828f562fa91a3e2fb141" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.74", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wynd-utils" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa37b3fba808df599acc6f0d7523b465baf47a0b0361867c4f1635eb53f72aa" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +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 = "bindgen" +version = "0.68.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.74", + "which", +] + +[[package]] +name = "bip32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58", + "hmac", + "k256 0.11.6", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bnum" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" + +[[package]] +name = "bootstrap-env" +version = "0.2.0" +dependencies = [ + "anyhow", + "cosm-orc", + "cosmwasm-std", + "cw-admin-factory", + "cw-utils 1.0.3", + "cw20 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-single 2.5.0", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "env_logger", + "serde", + "serde_json", + "serde_yaml", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] + +[[package]] +name = "btsg-ft-factory" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-token-staked", + "osmosis-std-derive", + "prost 0.12.3", + "prost-derive 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" +dependencies = [ + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "num-traits", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "config" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cosm-orc" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6676a17fddc94aac5fe07bad646d99b7f7cef1f0cc2c74b61af25733cbbb9f08" +dependencies = [ + "config", + "cosm-tome", + "erased-serde", + "log", + "serde", + "serde_json", + "thiserror", + "tokio", +] + +[[package]] +name = "cosm-tome" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "596064e3608349aa302eb68b2df8ed3a66bbb51d9b470dbd9afff70843e44642" +dependencies = [ + "async-trait", + "cosmrs 0.10.0", + "regex", + "schemars", + "serde", + "serde_json", + "thiserror", + "tonic 0.8.3", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20b42021d8488665b1a0d9748f1f81df7235362d194f44481e2e61bf376b77b4" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.23.9", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673d31bd830c0772d78545de20d975129b6ab2f7db4e4e9313c3b8777d319194" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.26.0", + "tonic 0.8.3", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.32.2", + "tonic 0.9.2", +] + +[[package]] +name = "cosmrs" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3903590099dcf1ea580d9353034c9ba1dbf55d1389a5bd2ade98535c3445d1f9" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.14.0", + "ecdsa 0.14.8", + "eyre", + "getrandom", + "k256 0.11.6", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint 0.23.9", + "tendermint-rpc 0.23.9", + "thiserror", +] + +[[package]] +name = "cosmrs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa07096219b1817432b8f1e47c22e928c64bbfd231fc08f0a98f0e7ddd602b7" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.15.0", + "ecdsa 0.14.8", + "eyre", + "getrandom", + "k256 0.11.6", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint 0.26.0", + "tendermint-rpc 0.26.0", + "thiserror", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256 0.13.3", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" +dependencies = [ + "base64 0.21.7", + "bech32", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ct-logs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" +dependencies = [ + "sct", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cw-address-like" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +dependencies = [ + "cosmwasm-std", +] + +[[package]] +name = "cw-admin-factory" +version = "2.5.0" +dependencies = [ + "bech32", + "cosmwasm-schema", + "cosmwasm-std", + "cw-admin-factory", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw4 2.5.0", + "osmosis-test-tube", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64bfeaf55f8dba5646cc3daddce17cd23a60f8e0c3fbacbe6735d287d7a6e33a" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468b8f2696f625c8e15b5468f9420c8eabfaf23cb4fd7e6c660fc7e0cc8d77b8" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-paginate-storage 0.1.0", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw721 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-core-interface" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c93e684945473777ebed2bcaf9f0af2291653f79d5c81774c6826350ba6d88de" +dependencies = [ + "cosmwasm-std", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw-core-interface" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "cosmwasm-std", + "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw2 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw-core-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f20a77489d2dc8a1c12cb0b9671b6cbdca88f12fe65e1a4ee9899490f7669dcc" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-core-macros" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "proc-macro2", + "quote", + "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" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", +] + +[[package]] +name = "cw-fund-distributor" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-voting-cw20-staked", + "thiserror", +] + +[[package]] +name = "cw-hooks" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "097ee97b99ecc90372eac3bcaf698d940a15f806f2ba1e1e901c729f6523e16e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "thiserror", +] + +[[package]] +name = "cw-hooks" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "thiserror", +] + +[[package]] +name = "cw-multi-test" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" +dependencies = [ + "anyhow", + "bech32", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "derivative", + "itertools 0.12.1", + "prost 0.12.3", + "schemars", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cw-ownable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-ownable-derive", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "thiserror", +] + +[[package]] +name = "cw-ownable-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-paginate-storage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b854833e07c557dee02d1b61a21bb0731743bb2e3bbdc3e446a0d8a38af40ec4" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.13.4", + "serde", +] + +[[package]] +name = "cw-paginate-storage" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9740c02c59072ad00de64cc60aae6ca492103dcefc0f7d3cc6f77d768f2ec70" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw-paginate-storage" +version = "2.5.0" +dependencies = [ + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw-payroll-factory" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw-vesting", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", + "wynd-utils", +] + +[[package]] +name = "cw-proposal-single" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6408483e1ac17a7e2b98ef6fa1379776964353bcbf501942d22ee1c1323117" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw3", + "dao-voting 0.1.0", + "indexable-hooks", + "proposal-hooks", + "schemars", + "serde", + "thiserror", + "vote-hooks", +] + +[[package]] +name = "cw-stake-tracker" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-wormhole", +] + +[[package]] +name = "cw-storage-plus" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-token-swap" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", +] + +[[package]] +name = "cw-tokenfactory-issuer" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-tokenfactory-types", + "cw2 1.1.2", + "dao-interface 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "prost 0.12.3", + "prost-derive 0.12.3", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cw-tokenfactory-types" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "dao-interface 2.5.0", + "osmosis-std", + "osmosis-std-derive", + "prost 0.12.3", + "prost-derive 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "cw-utils" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef842a1792e4285beff7b3b518705f760fa4111dc1e296e53f3e92d1ef7f6220" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 0.16.0", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw-vesting" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-stake-tracker", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw-wormhole", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-testing", + "serde", + "thiserror", + "wynd-utils", +] + +[[package]] +name = "cw-wormhole" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.16.0", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9671d7edef5608acaf5b2f1e473ee3f501eced2cd4f7392e2106c8cf02ba0720" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.11.1", + "schemars", + "serde", +] + +[[package]] +name = "cw20" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw20" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw20-base" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f6fc8c4cd451b418fa4f1ac2ea70595811fa9d8b4033617fe47953d7a93ceb" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "cw2 0.11.1", + "cw20 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-base" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-base" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-stake" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26f0d51ce27a97b51f66d737183845bc6d82f46f4b246dc959d1265d86906ccc" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-stake" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 0.2.6", + "dao-hooks 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "cw20-stake-external-rewards" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 0.13.4", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-hooks 2.5.0", + "stake-cw20-external-rewards", + "thiserror", +] + +[[package]] +name = "cw20-stake-reward-distributor" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "stake-cw20-reward-distributor", + "thiserror", +] + +[[package]] +name = "cw20-staked-balance-voting" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf8c2ee92372d35c3a48fd6ddd490a1a4426902748017dd0b7f551d06484e28" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "schemars", + "serde", +] + +[[package]] +name = "cw4-group" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6c95c89153e7831c8306c8eba40a3daa76f9c7b8f5179dd0b8628aca168ec7a" +dependencies = [ + "cosmwasm-std", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw4 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4-group" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4-voting" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw4 0.13.4", + "cw4-group 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035818368a74c07dd9ed5c5a93340199ba251530162010b9f34c3809e3b97df1" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw721" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 0.16.0", + "schemars", + "serde", +] + +[[package]] +name = "cw721" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw721-base" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.16.0", + "cw-utils 0.16.0", + "cw2 0.16.0", + "cw721 0.16.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721-base" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.16.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721-controllers" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "thiserror", +] + +[[package]] +name = "cw721-roles" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "dao-cw721-extensions", + "dao-testing", + "dao-voting-cw721-staked", + "serde", + "thiserror", +] + +[[package]] +name = "dao-cw721-extensions" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw4 1.1.2", +] + +[[package]] +name = "dao-dao-core" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd16c5f6f2760c66546e1e2f3781106dd796c8920847e78e5984922767cbc68" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-paginate-storage 2.4.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw721 0.18.0", + "dao-dao-macros 2.4.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-dao-core" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c3f39b7aaf9d913d0de8c8742c151011da00662acdbe95c33a5f7bad1b835a" +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 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dao-hooks" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c85abbadefe491d571f709464a8cfd2fb78b63b0cb6e6ef49104df249e28acc" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw4 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-hooks" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.5.0", + "cw4 1.1.2", + "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" +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-migrator" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-multi-test", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 0.13.4", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 0.2.6", + "cw20-stake 2.5.0", + "cw20-staked-balance-voting", + "cw4 0.13.4", + "cw4-voting", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approval-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4fe4e5b50b3081272557069dbecaf1e0984d1f2932d2e61418712460f8fd313" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-paginate-storage 2.4.2", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approval-single" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-approval-single 2.4.1", + "dao-pre-propose-base 2.5.0", + "dao-proposal-single 2.4.1", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approver" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-approval-single 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", +] + +[[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.2", + "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 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 2.5.0", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-multiple" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d6158aeddd2e080c730f1a2ac3814351cbcd38d61c38209dcf1e203d0e554a5" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-pre-propose-multiple" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-multiple 2.4.1", + "dao-proposal-multiple 2.4.1", + "dao-proposal-multiple 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", +] + +[[package]] +name = "dao-pre-propose-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30f96fb1898f94ea4fe5771f8ab5c2bc6237782e06bb599f070713d11d38c19e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-pre-propose-single" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-single 2.4.1", + "dao-proposal-single 2.4.1", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", +] + +[[package]] +name = "dao-proposal-condorcet" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.5.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-proposal-hook-counter" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "thiserror", +] + +[[package]] +name = "dao-proposal-incentives" +version = "2.4.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-proposal-incentives" +version = "2.4.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core", + "dao-hooks", + "dao-interface", + "dao-voting 2.4.0", + "thiserror", +] + +[[package]] +name = "dao-proposal-multiple" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51fac47816150063ef09b555f3466f8be99612b76860a20fba7c85bd1854beba" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "dao-dao-macros 2.4.2", + "dao-hooks 2.4.1", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-pre-propose-multiple 2.4.1", + "dao-voting 0.1.0", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-proposal-multiple" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "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", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-multiple 2.5.0", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "rand", + "thiserror", +] + +[[package]] +name = "dao-proposal-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce91710cfcff1af520cd0e885eee6972aeefbefc1c9da18349e66ab959269bb" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "dao-dao-macros 2.4.2", + "dao-hooks 2.4.1", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-voting 0.1.0", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-proposal-single" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-dao-core 2.5.0", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "thiserror", +] + +[[package]] +name = "dao-proposal-sudo" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-rewards-distributor" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "semver", + "thiserror", +] + +[[package]] +name = "dao-test-custom-factory" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-tokenfactory-issuer", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-testing" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-admin-factory", + "cw-core", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-proposal-single", + "cw-tokenfactory-issuer", + "cw-utils 1.0.3", + "cw-vesting", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "cw721-roles", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-multiple 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-condorcet", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-roles", + "dao-voting-cw721-staked", + "dao-voting-onft-staked", + "dao-voting-token-staked", + "osmosis-std", + "osmosis-test-tube", + "rand", + "serde", + "serde_json", + "stake-cw20", +] + +[[package]] +name = "dao-voting" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442d770933e3b3ecab4cfb4d6e9d054082b007d35fda3cf0c3d3ddd1cfa91782" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "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.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-voting" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw20-balance" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw20-staked" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw4" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba59e19abd4d51d6c3a37a84fb0c8cfe90e2f2ab551a610ec6749fcd09fc9e86" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-macros 2.4.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-voting-cw4" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw721-roles" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-controllers", + "cw721-roles", + "dao-cw721-extensions", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "thiserror", +] + +[[package]] +name = "dao-voting-cw721-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-controllers", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "serde", + "thiserror", +] + +[[package]] +name = "dao-voting-incentives" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-onft-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "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 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "omniflix-std", + "osmosis-test-tube", + "prost 0.12.3", + "prost-derive 0.12.3", + "serde", + "thiserror", +] + +[[package]] +name = "dao-voting-token-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "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 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "serde", + "thiserror", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.4.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-proxy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "hyper-rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", + "webpki", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "ct-logs", + "futures-util", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "webpki", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexable-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70922e1e0e68d99ec1a24446c70756cc3e56deaddb505b1f4b43914522d809" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "integration-tests" +version = "0.1.0" +dependencies = [ + "anyhow", + "assert_matches", + "cosm-orc", + "cosm-tome", + "cosmos-sdk-proto 0.19.0", + "cosmwasm-std", + "cw-utils 1.0.3", + "cw-vesting", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-roles", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw721-staked", + "env_logger", + "once_cell", + "rand", + "serde", + "serde_json", + "test-context", +] + +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.156" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +dependencies = [ + "memchr", +] + +[[package]] +name = "omniflix-std" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a662bd7782ef6ad1af3747a2b73d37f8e6a230bb7b1624d96c05b3567501600" +dependencies = [ + "chrono", + "cosmwasm-std", + "omniflix-std-derive", + "prost 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "omniflix-std-derive" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbd85582e3ef1a23fa7b12e0415ea604260c114e72faf40d829c2c40f1c745e" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "prost-types 0.11.9", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown 0.12.3", +] + +[[package]] +name = "osmosis-std" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7aa053bc3fad557ac90a0377688b400c395e2537f0f1de3293a15cad2e970" +dependencies = [ + "chrono", + "cosmwasm-std", + "osmosis-std-derive", + "prost 0.11.9", + "prost-types 0.11.9", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "osmosis-std-derive" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "prost-types 0.11.9", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "osmosis-test-tube" +version = "20.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" +dependencies = [ + "base64 0.21.7", + "bindgen", + "cosmrs 0.9.0", + "cosmwasm-std", + "osmosis-std", + "prost 0.11.9", + "serde", + "serde_json", + "test-tube", + "thiserror", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "pest_meta" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.74", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proposal-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a2f15b848398bad689771b35313c7e7095e772d444e299dbdb54b906691f8a" +dependencies = [ + "cosmwasm-std", + "indexable-hooks", + "schemars", + "serde", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost 0.12.3", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags 1.3.2", + "serde", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-native-certs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" +dependencies = [ + "openssl-probe", + "rustls", + "schannel", + "security-framework", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.74", +] + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.9", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-cw-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.4.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + +[[package]] +name = "stake-cw20" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfbd45133276dbe4d6588899f4d4d06fdb9f16921fd1394affc0bccc9a5cb0b6" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.11.1", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "cw2 0.11.1", + "cw20 0.11.1", + "cw20-base 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "stake-cw20-external-rewards" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9bbc1e4b7a932957a05a76921015a849b234c3f25e59fe1fd0d2eab71654bc" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "stake-cw20-reward-distributor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4260ff7aec6dddb43cb5f1104ef5cebe2787853bc83af9172ce5b828b577c4c5" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tendermint" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467f82178deeebcd357e1273a0c0b77b9a8a0313ef7c07074baebe99d87851f4" +dependencies = [ + "async-trait", + "bytes", + "ed25519", + "ed25519-dalek", + "flex-error", + "futures", + "k256 0.11.6", + "num-traits", + "once_cell", + "prost 0.11.9", + "prost-types 0.11.9", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature 1.6.4", + "subtle", + "subtle-encoding", + "tendermint-proto 0.23.9", + "time", + "zeroize", +] + +[[package]] +name = "tendermint" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" +dependencies = [ + "async-trait", + "bytes", + "ed25519", + "ed25519-dalek", + "flex-error", + "futures", + "k256 0.11.6", + "num-traits", + "once_cell", + "prost 0.11.9", + "prost-types 0.11.9", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature 1.6.4", + "subtle", + "subtle-encoding", + "tendermint-proto 0.26.0", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d42ee0abc27ef5fc34080cce8d43c189950d331631546e7dfb983b6274fa327" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint 0.23.9", + "toml", + "url", +] + +[[package]] +name = "tendermint-config" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202a2f19502c03b353d8157694ed24fbc58c3dd64a92a5b0cb80b79c82af5be4" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint 0.26.0", + "toml", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ce80bf536476db81ecc9ebab834dc329c9c1509a694f211a73858814bfe023" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-proto" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "974d6330a19dfa6720e9f663fc59101d207a817db3f9c730d3f31caaa565b574" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-proto" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-rpc" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f14aafe3528a0f75e9f3f410b525617b2de16c4b7830a21f717eee62882ec60" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "peg", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle-encoding", + "tendermint 0.23.9", + "tendermint-config 0.23.9", + "tendermint-proto 0.23.9", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tendermint-rpc" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5d87fa5429bd2ee39c4809dd546096daf432de9b71157bc12c182ab5bae7ea7" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "peg", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle", + "subtle-encoding", + "tendermint 0.26.0", + "tendermint-config 0.26.0", + "tendermint-proto 0.26.0", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-context" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6965c21232186af0092233c18030fe607cfc3960dbabb209325272458eeea" +dependencies = [ + "async-trait", + "futures", + "test-context-macros", +] + +[[package]] +name = "test-context-macros" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" +dependencies = [ + "quote", + "syn 2.0.74", +] + +[[package]] +name = "test-tube" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e79c7af10967dd3383ee5aae3810637cc3f2fd040f87f862c02151db060628" +dependencies = [ + "base64 0.13.1", + "cosmrs 0.9.0", + "cosmwasm-std", + "osmosis-std", + "prost 0.11.9", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "time" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +dependencies = [ + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "prost-derive 0.11.9", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vote-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef617ad17edd195f8a3bce72498bfcc406a27cecfc23828f562fa91a3e2fb141" +dependencies = [ + "cosmwasm-std", + "indexable-hooks", + "schemars", + "serde", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.74", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wynd-utils" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa37b3fba808df599acc6f0d7523b465baf47a0b0361867c4f1635eb53f72aa" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index 97106c68a..d80c6b322 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -23,6 +23,7 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } dao-hooks = { workspace = true } dao-interface = { workspace = true } +dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 6f10d0d09..989142962 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,11 +1,12 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; use dao_hooks::vote::VoteHookMsg; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::{DAO, VOTING_INCENTIVES}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -15,13 +16,17 @@ pub fn instantiate( deps: DepsMut, _env: Env, info: MessageInfo, - _msg: InstantiateMsg, + msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save config + // Save DAO, assumes the sender is the DAO + DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; - // Check initial deposit + // Save voting incentives config + + // TODO Check initial deposit is enough to pay out rewards for at + // least one epoch Ok(Response::new() .add_attribute("method", "instantiate") @@ -41,26 +46,47 @@ pub fn execute( } } +// TODO how to claim for many epochs efficiently? pub fn execute_claim( deps: DepsMut, env: Env, info: MessageInfo, ) -> Result { + // Check epoch should advance + + // Save last claimed epoch + + // Load user vote count for epoch? + + // Load prop count for epoch + + // Load voting incentives config + let voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; + + // Need total vote count for epoch + // Rewards = (user vote count / prop count) / total_vote_count * voting incentives + + // Pay out rewards + Ok(Response::default().add_attribute("action", "claim")) } +// TODO support cw20 tokens +// TODO make sure config can't lock DAO pub fn execute_vote_hook( deps: DepsMut, env: Env, info: MessageInfo, msg: VoteHookMsg, ) -> Result { - // Check epoch + // Check epoch should advance + + // TODO need some state to handle this + // Check that the vote is not a changed vote (i.e. the user has already voted + // on the prop). - // TODO what is the best data structure to use here? - // Save vote? Save prop ID? - // Save (user, epoch, vote count) - // Save (epoch, prop count) + // Save (user, epoch), vote count + // Update (epoch, prop count) Ok(Response::default().add_attribute("action", "vote_hook")) } @@ -69,6 +95,7 @@ pub fn execute_vote_hook( pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Rewards { address } => unimplemented!(), + QueryMsg::Config {} => unimplemented!(), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index 6902586b6..d1800adbc 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -3,6 +3,7 @@ pub mod contract; mod error; pub mod msg; +pub mod state; #[cfg(test)] mod tests; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 67642be33..5298657e6 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,13 +1,14 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Timestamp; use dao_hooks::vote::VoteHookMsg; +use crate::state::VotingIncentives; + #[cw_serde] pub struct InstantiateMsg { /// DAO address pub dao: String, - /// Epoch duration in seconds. Used for reward calculation. - pub epoch_duration: Timestamp, + /// Rewards to pay out for voting. + pub voting_incentives: VotingIncentives, } #[cw_serde] @@ -21,10 +22,21 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { + /// Returns the config. + #[returns(ConfigResponse)] + Config {}, /// Returns the rewards for the given address. #[returns(cosmwasm_std::Uint128)] Rewards { address: String }, } +#[cw_serde] +pub struct ConfigResponse { + /// DAO address + pub dao: String, + /// Rewards to pay out for voting. + pub voting_incentives: VotingIncentives, +} + #[cw_serde] pub struct MigrateMsg {} diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs new file mode 100644 index 000000000..730cd7fe3 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -0,0 +1,33 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin, Timestamp}; +use cw_storage_plus::{Item, Map}; + +/// The address of the DAO this contract serves +pub const DAO: Item = Item::new("dao"); + +/// Incentives for voting +#[cw_serde] +pub struct VotingIncentives { + /// Epoch duration in seconds. Used for reward calculation. + pub epoch_duration: Timestamp, + /// The rewards to pay out per epoch. + pub rewards_per_epoch: Coin, +} + +/// Holds VotingIncentives state +pub const VOTING_INCENTIVES: Item = Item::new("voting_incentives"); + +/// The current epoch +pub const EPOCH: Item = Item::new("epoch"); + +/// A map of addresses to their last claimed epoch +pub const LAST_CLAIMED_EPOCHS: Map = Map::new("last_claimed_epoch"); + +/// A map of epochs to prop count +pub const EPOCH_PROPOSAL_COUNT: Map = Map::new("epoch_proposal_count"); + +/// A map of epochs to total vote count +pub const EPOCH_TOTAL_VOTE_COUNT: Map = Map::new("epoch_total_vote_count"); + +/// A map of user addresses + epoch to vote count +pub const USER_EPOCH_VOTE_COUNT: Map<(Addr, u64), u64> = Map::new("user_epoch_vote_count"); From 76f5ca18249b9c445784c98e704ac6590393a9e2 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 15:57:30 +0100 Subject: [PATCH 26/47] Proposal incentives fixups and notes --- .../external/dao-proposal-incentives/README.md | 7 +++++++ .../dao-proposal-incentives/src/contract.rs | 14 +++++++++++--- .../external/dao-proposal-incentives/src/error.rs | 14 ++++++++++---- .../external/dao-proposal-incentives/src/msg.rs | 4 ++-- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 20a0f9ff4..de17171b8 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -4,3 +4,10 @@ [![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) Allows for DAOs to offer incentives for making successful proposals. + +To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When someone successfully passes a proposal the specified rewards are automatically paid out. + +## TODO +- [ ] Unit and Integration tests with a full DAO +- [ ] Support Cw20 +- [ ] Add more info to the readme and delete this TODO section diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs index 8e01dacb3..5e7cabcea 100644 --- a/contracts/external/dao-proposal-incentives/src/contract.rs +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -5,6 +5,7 @@ use cosmwasm_std::{ SubMsg, }; use cw2::set_contract_version; +use cw_utils::must_pay; use dao_hooks::proposal::ProposalHookMsg; use dao_voting::status::Status; @@ -32,8 +33,15 @@ pub fn instantiate( // Save proposal incentives config PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; - // TODO Check initial deposit contains enough funds to pay out rewards + // Check initial deposit contains enough funds to pay out rewards // for at least one proposal + let amount = must_pay(&info, &msg.proposal_incentives.rewards_per_proposal.denom)?; + if amount < msg.proposal_incentives.rewards_per_proposal.amount { + return Err(ContractError::InsufficientInitialDeposit { + expected: msg.proposal_incentives.rewards_per_proposal.amount, + actual: amount, + }); + }; Ok(Response::new() .add_attribute("method", "instantiate") @@ -55,7 +63,7 @@ pub fn execute( // TODO support cw20 tokens pub fn execute_proposal_hook( deps: DepsMut, - env: Env, + _env: Env, info: MessageInfo, msg: ProposalHookMsg, ) -> Result { @@ -101,7 +109,7 @@ pub fn query_config(deps: Deps) -> StdResult { let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; to_json_binary(&ConfigResponse { - dao, + dao: dao.to_string(), proposal_incentives, }) } diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index 56c764778..69d218ddc 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -1,5 +1,5 @@ -use cosmwasm_std::StdError; -use cw_utils::ParseReplyError; +use cosmwasm_std::{StdError, Uint128}; +use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; #[derive(Error, Debug)] @@ -7,12 +7,18 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, + #[error("{0}")] + PaymentError(#[from] PaymentError), + + #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] + InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("Unauthorized")] + Unauthorized {}, + #[error("An unknown reply ID was received.")] UnknownReplyID {}, } diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs index 0c714bcce..d3290bbde 100644 --- a/contracts/external/dao-proposal-incentives/src/msg.rs +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use dao_hooks::{proposal::ProposalHookMsg, vote::VoteHookMsg}; +use dao_hooks::proposal::ProposalHookMsg; -use crate::state::{ProposalIncentives, VotingIncentives}; +use crate::state::ProposalIncentives; #[cw_serde] pub struct InstantiateMsg { From 40dd5fef51bc1c529779e4bd5b238a515a0ddd77 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 15:57:50 +0100 Subject: [PATCH 27/47] Voting incentives checks and notes --- .../external/dao-voting-incentives/README.md | 25 +++++++++++++------ .../dao-voting-incentives/src/contract.rs | 14 ++++++++--- .../dao-voting-incentives/src/error.rs | 16 ++++++++---- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index 2ee2a1d98..5da24b99b 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,14 +1,23 @@ -# cw-admin-factory +# dao-voting-incentives -[![cw-admin-factory on crates.io](https://img.shields.io/crates/v/cw-admin-factory.svg?logo=rust)](https://crates.io/crates/cw-admin-factory) -[![docs.rs](https://img.shields.io/docsrs/cw-admin-factory?logo=docsdotrs)](https://docs.rs/cw-admin-factory/latest/cw_admin_factory/) +[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) -Serves as a factory that instantiates contracts and sets them as their -own wasm admins. +Allows for DAOs to offer incentives for voting on DAO proposals. -Useful for allowing contracts (e.g. DAOs) to migrate themselves. +When creating this contract, the DAO specifies an `epoch_duration` and an amount to pay out per epoch. Then, the DAO needs to add this contract as a `VoteHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When DAO members vote, this contract keeps track of the proposals and who voted. -Example instantiation flow: +At the end of the epoch, rewards are payable as follows: -![](https://bafkreibqsrdnht5chc5mdzbb6pgiyqfjke3yvukvjrokyefwwbl3k3iwaa.ipfs.nftstorage.link) +``` +rewards = (user vote count / prop count) / total_vote_count * voting incentives +``` +If no proposals happen during an epoch, no rewards are paid out. + +## TODO +- [ ] Unit and Integration tests with a full DAO +- [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) +- [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. +- [ ] Support Cw20. +- [ ] Add more info to the readme and delete this TODO section. diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 989142962..28ff99777 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -2,6 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; +use cw_utils::must_pay; use dao_hooks::vote::VoteHookMsg; use crate::error::ContractError; @@ -24,9 +25,16 @@ pub fn instantiate( DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; // Save voting incentives config - - // TODO Check initial deposit is enough to pay out rewards for at - // least one epoch + VOTING_INCENTIVES.save(deps.storage, &msg.voting_incentives)?; + + // Check initial deposit is enough to pay out rewards for at least one epoch + let amount = must_pay(&info, &msg.voting_incentives.rewards_per_epoch.denom)?; + if amount < msg.voting_incentives.rewards_per_epoch.amount { + return Err(ContractError::InsufficientInitialDeposit { + expected: msg.voting_incentives.rewards_per_epoch.amount, + actual: amount, + }); + }; Ok(Response::new() .add_attribute("method", "instantiate") diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 56c764778..2b1469dcb 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -1,5 +1,5 @@ -use cosmwasm_std::StdError; -use cw_utils::ParseReplyError; +use cosmwasm_std::{StdError, Uint128}; +use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; #[derive(Error, Debug)] @@ -7,12 +7,18 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("Unauthorized")] - Unauthorized {}, - #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("{0}")] + PaymentError(#[from] PaymentError), + + #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] + InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + + #[error("Unauthorized")] + Unauthorized {}, + #[error("An unknown reply ID was received.")] UnknownReplyID {}, } From 632bfe45f8658bfd49eb1b5472ffc723d8ec89f2 Mon Sep 17 00:00:00 2001 From: Jake Hartnell Date: Thu, 25 Jan 2024 16:00:52 +0100 Subject: [PATCH 28/47] More notes --- contracts/external/dao-proposal-incentives/README.md | 1 + contracts/external/dao-voting-incentives/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index de17171b8..7fea7973b 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -10,4 +10,5 @@ To setup this contract, the DAO needs to add this contract as a `ProposalHook` t ## TODO - [ ] Unit and Integration tests with a full DAO - [ ] Support Cw20 +- [ ] Use `cw-ownable` to configure a contract owner who can update the proposal incentives config. - [ ] Add more info to the readme and delete this TODO section diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index 5da24b99b..f41943baf 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -20,4 +20,5 @@ If no proposals happen during an epoch, no rewards are paid out. - [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) - [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. - [ ] Support Cw20. +- [ ] Use `cw-ownable` to configure a contract owner who can update the voting incentives config. - [ ] Add more info to the readme and delete this TODO section. From d2c39befd35b10536456d550cfb1a095e62eabac Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 10:33:44 -0600 Subject: [PATCH 29/47] Proposal Incentives --- Cargo.lock | 10855 ++++++++-------- Cargo.toml | 1 + contracts/dao-dao-core/src/contract.rs | 8 + .../dao-proposal-incentives/Cargo.toml | 8 +- .../dao-proposal-incentives/README.md | 8 +- .../dao-proposal-incentives/src/contract.rs | 113 +- .../dao-proposal-incentives/src/error.rs | 14 +- .../dao-proposal-incentives/src/execute.rs | 112 + .../dao-proposal-incentives/src/helpers.rs | 31 + .../dao-proposal-incentives/src/lib.rs | 3 + .../dao-proposal-incentives/src/msg.rs | 34 +- .../dao-proposal-incentives/src/query.rs | 14 + .../dao-proposal-incentives/src/state.rs | 18 +- .../dao-proposal-incentives/src/tests.rs | 528 +- .../external/dao-voting-incentives/Cargo.toml | 1 + .../dao-voting-incentives/src/contract.rs | 2 +- .../dao-voting-incentives/src/tests.rs | 167 - .../dao-proposal-condorcet/src/contract.rs | 1 + .../dao-proposal-multiple/src/contract.rs | 7 + .../dao-proposal-multiple/src/proposal.rs | 8 + .../proposal/dao-proposal-single/Cargo.toml | 1 + .../dao-proposal-single/src/contract.rs | 7 + .../dao-proposal-single/src/proposal.rs | 8 + packages/dao-dao-macros/src/lib.rs | 3 + packages/dao-dao-macros/tests/govmod.rs | 1 + packages/dao-hooks/src/proposal.rs | 2 +- packages/dao-interface/src/msg.rs | 3 + packages/dao-interface/src/proposal.rs | 11 + packages/dao-testing/Cargo.toml | 1 + packages/dao-testing/src/contracts.rs | 10 + 30 files changed, 6144 insertions(+), 5836 deletions(-) create mode 100644 contracts/external/dao-proposal-incentives/src/execute.rs create mode 100644 contracts/external/dao-proposal-incentives/src/helpers.rs create mode 100644 contracts/external/dao-proposal-incentives/src/query.rs diff --git a/Cargo.lock b/Cargo.lock index 63f0aba9f..6e836dcdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5432 +1,5423 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "async-trait" -version = "0.1.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -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 = "bindgen" -version = "0.68.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.74", - "which", -] - -[[package]] -name = "bip32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" -dependencies = [ - "bs58", - "hmac", - "k256 0.11.6", - "once_cell", - "pbkdf2", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" - -[[package]] -name = "bootstrap-env" -version = "0.2.0" -dependencies = [ - "anyhow", - "cosm-orc", - "cosmwasm-std", - "cw-admin-factory", - "cw-utils 1.0.3", - "cw20 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "env_logger", - "serde", - "serde_json", - "serde_yaml", -] - -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -dependencies = [ - "sha2 0.9.9", -] - -[[package]] -name = "btsg-ft-factory" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-token-staked", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" -dependencies = [ - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "num-traits", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "config" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" -dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml", - "yaml-rust", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cosm-orc" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6676a17fddc94aac5fe07bad646d99b7f7cef1f0cc2c74b61af25733cbbb9f08" -dependencies = [ - "config", - "cosm-tome", - "erased-serde", - "log", - "serde", - "serde_json", - "thiserror", - "tokio", -] - -[[package]] -name = "cosm-tome" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "596064e3608349aa302eb68b2df8ed3a66bbb51d9b470dbd9afff70843e44642" -dependencies = [ - "async-trait", - "cosmrs 0.10.0", - "regex", - "schemars", - "serde", - "serde_json", - "thiserror", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b42021d8488665b1a0d9748f1f81df7235362d194f44481e2e61bf376b77b4" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.23.9", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673d31bd830c0772d78545de20d975129b6ab2f7db4e4e9313c3b8777d319194" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.26.0", - "tonic 0.8.3", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tendermint-proto 0.32.2", - "tonic 0.9.2", -] - -[[package]] -name = "cosmrs" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3903590099dcf1ea580d9353034c9ba1dbf55d1389a5bd2ade98535c3445d1f9" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.14.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-rpc 0.23.9", - "thiserror", -] - -[[package]] -name = "cosmrs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa07096219b1817432b8f1e47c22e928c64bbfd231fc08f0a98f0e7ddd602b7" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.15.0", - "ecdsa 0.14.8", - "eyre", - "getrandom", - "k256 0.11.6", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-rpc 0.26.0", - "thiserror", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" -dependencies = [ - "digest 0.10.7", - "ed25519-zebra", - "k256 0.13.3", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-std" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" -dependencies = [ - "base64 0.21.7", - "bech32", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.8", - "static_assertions", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-address-like" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" -dependencies = [ - "cosmwasm-std", -] - -[[package]] -name = "cw-admin-factory" -version = "2.5.0" -dependencies = [ - "bech32", - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "osmosis-test-tube", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bfeaf55f8dba5646cc3daddce17cd23a60f8e0c3fbacbe6735d287d7a6e33a" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-controllers" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468b8f2696f625c8e15b5468f9420c8eabfaf23cb4fd7e6c660fc7e0cc8d77b8" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-paginate-storage 0.1.0", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw721 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c93e684945473777ebed2bcaf9f0af2291653f79d5c81774c6826350ba6d88de" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-interface" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw2 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20a77489d2dc8a1c12cb0b9671b6cbdca88f12fe65e1a4ee9899490f7669dcc" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-core-macros" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "proc-macro2", - "quote", - "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" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-fund-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-voting-cw20-staked", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "097ee97b99ecc90372eac3bcaf698d940a15f806f2ba1e1e901c729f6523e16e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" -dependencies = [ - "anyhow", - "bech32", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "derivative", - "itertools 0.12.1", - "prost 0.12.3", - "schemars", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-ownable" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw-ownable-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-paginate-storage" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b854833e07c557dee02d1b61a21bb0731743bb2e3bbdc3e446a0d8a38af40ec4" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9740c02c59072ad00de64cc60aae6ca492103dcefc0f7d3cc6f77d768f2ec70" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-paginate-storage" -version = "2.5.0" -dependencies = [ - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-payroll-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-proposal-single" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6408483e1ac17a7e2b98ef6fa1379776964353bcbf501942d22ee1c1323117" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw3", - "dao-voting 0.1.0", - "indexable-hooks", - "proposal-hooks", - "schemars", - "serde", - "thiserror", - "vote-hooks", -] - -[[package]] -name = "cw-stake-tracker" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-wormhole", -] - -[[package]] -name = "cw-storage-plus" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-token-swap" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-issuer" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-types", - "cw2 1.1.2", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cw-tokenfactory-types" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "dao-interface 2.5.0", - "osmosis-std", - "osmosis-std-derive", - "prost 0.12.3", - "prost-derive 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "cw-utils" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef842a1792e4285beff7b3b518705f760fa4111dc1e296e53f3e92d1ef7f6220" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 0.16.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-utils" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-vesting" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-stake-tracker", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw-wormhole", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-testing", - "serde", - "thiserror", - "wynd-utils", -] - -[[package]] -name = "cw-wormhole" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw2" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9671d7edef5608acaf5b2f1e473ee3f501eced2cd4f7392e2106c8cf02ba0720" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f6fc8c4cd451b418fa4f1ac2ea70595811fa9d8b4033617fe47953d7a93ceb" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f0d51ce27a97b51f66d737183845bc6d82f46f4b246dc959d1265d86906ccc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-stake" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-ownable", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "dao-hooks 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "cw20-stake-external-rewards" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-hooks 2.5.0", - "stake-cw20-external-rewards", - "thiserror", -] - -[[package]] -name = "cw20-stake-reward-distributor" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "stake-cw20-reward-distributor", - "thiserror", -] - -[[package]] -name = "cw20-staked-balance-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf8c2ee92372d35c3a48fd6ddd490a1a4426902748017dd0b7f551d06484e28" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw3" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw4" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", -] - -[[package]] -name = "cw4-group" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6c95c89153e7831c8306c8eba40a3daa76f9c7b8f5179dd0b8628aca168ec7a" -dependencies = [ - "cosmwasm-std", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-group" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw4-voting" -version = "0.1.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw4 0.13.4", - "cw4-group 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035818368a74c07dd9ed5c5a93340199ba251530162010b9f34c3809e3b97df1" -dependencies = [ - "cosmwasm-std", - "cw-utils 0.13.4", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 0.16.0", - "schemars", - "serde", -] - -[[package]] -name = "cw721" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils 1.0.3", - "schemars", - "serde", -] - -[[package]] -name = "cw721-base" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.16.0", - "cw-utils 0.16.0", - "cw2 0.16.0", - "cw721 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-base" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.16.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-controllers" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "thiserror", -] - -[[package]] -name = "cw721-roles" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-cw721-extensions", - "dao-testing", - "dao-voting-cw721-staked", - "serde", - "thiserror", -] - -[[package]] -name = "dao-cw721-extensions" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw4 1.1.2", -] - -[[package]] -name = "dao-dao-core" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd16c5f6f2760c66546e1e2f3781106dd796c8920847e78e5984922767cbc68" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw721 0.18.0", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-dao-core" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c3f39b7aaf9d913d0de8c8742c151011da00662acdbe95c33a5f7bad1b835a" -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 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dao-hooks" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c85abbadefe491d571f709464a8cfd2fb78b63b0cb6e6ef49104df249e28acc" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw4 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-hooks" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw4 1.1.2", - "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" -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-migrator" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", - "cw-multi-test", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 0.13.4", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 0.2.6", - "cw20-stake 2.5.0", - "cw20-staked-balance-voting", - "cw4 0.13.4", - "cw4-voting", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4fe4e5b50b3081272557069dbecaf1e0984d1f2932d2e61418712460f8fd313" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-paginate-storage 2.4.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approval-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-paginate-storage 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.4.1", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-approver" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-approval-single 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", -] - -[[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.2", - "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 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 2.5.0", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6158aeddd2e080c730f1a2ac3814351cbcd38d61c38209dcf1e203d0e554a5" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-multiple" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.4.1", - "dao-proposal-multiple 2.4.1", - "dao-proposal-multiple 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f96fb1898f94ea4fe5771f8ab5c2bc6237782e06bb599f070713d11d38c19e" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw2 1.1.2", - "dao-pre-propose-base 2.4.1", - "dao-voting 2.4.1", -] - -[[package]] -name = "dao-pre-propose-single" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.4.1", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.4.1", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.4.1", - "dao-proposal-single 2.4.1", - "dao-proposal-single 2.5.0", - "dao-testing", - "dao-voting 2.4.1", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.4.1", - "dao-voting-cw4 2.5.0", -] - -[[package]] -name = "dao-proposal-condorcet" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw4 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-proposal-hook-counter" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "thiserror", -] - -[[package]] -name = "dao-proposal-incentives" -version = "2.4.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-single 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-proposal-incentives" -version = "2.4.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core", - "dao-hooks", - "dao-interface", - "dao-voting 2.4.0", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fac47816150063ef09b555f3466f8be99612b76860a20fba7c85bd1854beba" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-pre-propose-multiple 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-multiple" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "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", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "rand", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce91710cfcff1af520cd0e885eee6972aeefbefc1c9da18349e66ab959269bb" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-hooks 2.4.2", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "dao-dao-macros 2.4.2", - "dao-hooks 2.4.1", - "dao-interface 2.4.1", - "dao-pre-propose-base 2.4.1", - "dao-voting 0.1.0", - "dao-voting 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-proposal-single" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-core", - "cw-denom 2.5.0", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-proposal-single", - "cw-storage-plus 1.2.0", - "cw-utils 0.13.4", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-dao-core 2.5.0", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-base 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-testing", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "thiserror", -] - -[[package]] -name = "dao-proposal-sudo" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-rewards-distributor" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-staked", - "dao-voting-token-staked", - "semver", - "thiserror", -] - -[[package]] -name = "dao-test-custom-factory" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-testing" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-admin-factory", - "cw-core", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-proposal-single", - "cw-tokenfactory-issuer", - "cw-utils 1.0.3", - "cw-vesting", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw4 1.1.2", - "cw4-group 1.1.2", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-multiple 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-condorcet", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 0.1.0", - "dao-voting 2.5.0", - "dao-voting-cw20-balance", - "dao-voting-cw20-staked", - "dao-voting-cw4 2.5.0", - "dao-voting-cw721-roles", - "dao-voting-cw721-staked", - "dao-voting-onft-staked", - "dao-voting-token-staked", - "osmosis-std", - "osmosis-test-tube", - "rand", - "serde", - "serde_json", - "stake-cw20", -] - -[[package]] -name = "dao-voting" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442d770933e3b3ecab4cfb4d6e9d054082b007d35fda3cf0c3d3ddd1cfa91782" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "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.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-denom 2.5.0", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw20 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-balance" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw20-staked" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-voting 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba59e19abd4d51d6c3a37a84fb0c8cfe90e2f2ab551a610ec6749fcd09fc9e86" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.4.2", - "dao-interface 2.4.1", - "thiserror", -] - -[[package]] -name = "dao-voting-cw4" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw4-group 1.1.2", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-roles" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw4 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "cw721-roles", - "dao-cw721-extensions", - "dao-dao-macros 2.5.0", - "dao-interface 2.5.0", - "dao-testing", - "thiserror", -] - -[[package]] -name = "dao-voting-cw721-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "cw-hooks 2.5.0", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-controllers", - "dao-dao-macros 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-incentives" -version = "2.5.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw-utils 1.0.3", - "cw2 1.1.2", - "cw20-base 1.1.2", - "dao-dao-core 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "thiserror", -] - -[[package]] -name = "dao-voting-onft-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "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 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "omniflix-std", - "osmosis-test-tube", - "prost 0.12.3", - "prost-derive 0.12.3", - "serde", - "thiserror", -] - -[[package]] -name = "dao-voting-token-staked" -version = "2.5.0" -dependencies = [ - "anyhow", - "cosmwasm-schema", - "cosmwasm-std", - "cw-controllers 1.1.2", - "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 2.5.0", - "dao-hooks 2.5.0", - "dao-interface 2.5.0", - "dao-proposal-hook-counter", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-testing", - "dao-voting 2.5.0", - "osmosis-std", - "osmosis-test-tube", - "serde", - "thiserror", -] - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der 0.7.9", - "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", -] - -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek", - "ed25519", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", - "digest 0.10.7", - "ff 0.13.0", - "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1 0.7.3", - "subtle", - "zeroize", -] - -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.0", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.4.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "hyper-rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "tower-service", - "webpki", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "webpki", - "webpki-roots", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexable-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d70922e1e0e68d99ec1a24446c70756cc3e56deaddb505b1f4b43914522d809" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.13.4", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "integration-tests" -version = "0.1.0" -dependencies = [ - "anyhow", - "assert_matches", - "cosm-orc", - "cosm-tome", - "cosmos-sdk-proto 0.19.0", - "cosmwasm-std", - "cw-utils 1.0.3", - "cw-vesting", - "cw20 1.1.2", - "cw20-base 1.1.2", - "cw20-stake 2.5.0", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-roles", - "dao-dao-core 2.5.0", - "dao-interface 2.5.0", - "dao-pre-propose-single 2.5.0", - "dao-proposal-single 2.5.0", - "dao-test-custom-factory", - "dao-voting 2.5.0", - "dao-voting-cw20-staked", - "dao-voting-cw721-staked", - "env_logger", - "once_cell", - "rand", - "serde", - "serde_json", - "test-context", -] - -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", - "sha3", -] - -[[package]] -name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" -dependencies = [ - "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", - "once_cell", - "sha2 0.10.8", - "signature 2.2.0", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.156" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" - -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.36.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" -dependencies = [ - "memchr", -] - -[[package]] -name = "omniflix-std" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a662bd7782ef6ad1af3747a2b73d37f8e6a230bb7b1624d96c05b3567501600" -dependencies = [ - "chrono", - "cosmwasm-std", - "omniflix-std-derive", - "prost 0.12.3", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "omniflix-std-derive" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbd85582e3ef1a23fa7b12e0415ea604260c114e72faf40d829c2c40f1c745e" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "osmosis-std" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d7aa053bc3fad557ac90a0377688b400c395e2537f0f1de3293a15cad2e970" -dependencies = [ - "chrono", - "cosmwasm-std", - "osmosis-std-derive", - "prost 0.11.9", - "prost-types 0.11.9", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "osmosis-std-derive" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "osmosis-test-tube" -version = "20.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" -dependencies = [ - "base64 0.21.7", - "bindgen", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "test-tube", - "thiserror", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "pest_meta" -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" -dependencies = [ - "once_cell", - "pest", - "sha2 0.10.8", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.9", - "spki 0.7.3", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" -dependencies = [ - "proc-macro2", - "syn 2.0.74", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proposal-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a2f15b848398bad689771b35313c7e7095e772d444e299dbdb54b906691f8a" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" -dependencies = [ - "bytes", - "prost-derive 0.12.3", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-derive" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" -dependencies = [ - "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - -[[package]] -name = "prost-types" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" -dependencies = [ - "prost 0.12.3", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "serde", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls", - "schannel", - "security-framework", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.74", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.9", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-cw-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.208" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_json" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.4.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.9", -] - -[[package]] -name = "stake-cw20" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfbd45133276dbe4d6588899f4d4d06fdb9f16921fd1394affc0bccc9a5cb0b6" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.11.1", - "cw-storage-plus 0.11.1", - "cw-utils 0.11.1", - "cw2 0.11.1", - "cw20 0.11.1", - "cw20-base 0.11.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-external-rewards" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9bbc1e4b7a932957a05a76921015a849b234c3f25e59fe1fd0d2eab71654bc" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers 0.13.4", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "stake-cw20-reward-distributor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4260ff7aec6dddb43cb5f1104ef5cebe2787853bc83af9172ce5b828b577c4c5" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.13.4", - "cw-utils 0.13.4", - "cw2 0.13.4", - "cw20 0.13.4", - "cw20-base 0.13.4", - "cw20-stake 0.2.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "tendermint" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467f82178deeebcd357e1273a0c0b77b9a8a0313ef7c07074baebe99d87851f4" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.23.9", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" -dependencies = [ - "async-trait", - "bytes", - "ed25519", - "ed25519-dalek", - "flex-error", - "futures", - "k256 0.11.6", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "ripemd160", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.9.9", - "signature 1.6.4", - "subtle", - "subtle-encoding", - "tendermint-proto 0.26.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42ee0abc27ef5fc34080cce8d43c189950d331631546e7dfb983b6274fa327" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.23.9", - "toml", - "url", -] - -[[package]] -name = "tendermint-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202a2f19502c03b353d8157694ed24fbc58c3dd64a92a5b0cb80b79c82af5be4" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.26.0", - "toml", - "url", -] - -[[package]] -name = "tendermint-proto" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ce80bf536476db81ecc9ebab834dc329c9c1509a694f211a73858814bfe023" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974d6330a19dfa6720e9f663fc59101d207a817db3f9c730d3f31caaa565b574" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.23.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f14aafe3528a0f75e9f3f410b525617b2de16c4b7830a21f717eee62882ec60" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle-encoding", - "tendermint 0.23.9", - "tendermint-config 0.23.9", - "tendermint-proto 0.23.9", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tendermint-rpc" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5d87fa5429bd2ee39c4809dd546096daf432de9b71157bc12c182ab5bae7ea7" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls", - "peg", - "pin-project", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.26.0", - "tendermint-config 0.26.0", - "tendermint-proto 0.26.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test-context" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6965c21232186af0092233c18030fe607cfc3960dbabb209325272458eeea" -dependencies = [ - "async-trait", - "futures", - "test-context-macros", -] - -[[package]] -name = "test-context-macros" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" -dependencies = [ - "quote", - "syn 2.0.74", -] - -[[package]] -name = "test-tube" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e79c7af10967dd3383ee5aae3810637cc3f2fd040f87f862c02151db060628" -dependencies = [ - "base64 0.13.1", - "cosmrs 0.9.0", - "cosmwasm-std", - "osmosis-std", - "prost 0.11.9", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "time" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" -dependencies = [ - "libc", - "num_threads", - "time-macros", -] - -[[package]] -name = "time-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.39.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "tonic" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.13.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "prost-derive 0.11.9", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vote-hooks" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef617ad17edd195f8a3bce72498bfcc406a27cecfc23828f562fa91a3e2fb141" -dependencies = [ - "cosmwasm-std", - "indexable-hooks", - "schemars", - "serde", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.74", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wynd-utils" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa37b3fba808df599acc6f0d7523b465baf47a0b0361867c4f1635eb53f72aa" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.74", -] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +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 = "bindgen" +version = "0.68.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.74", + "which", +] + +[[package]] +name = "bip32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58", + "hmac", + "k256 0.11.6", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bnum" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" + +[[package]] +name = "bootstrap-env" +version = "0.2.0" +dependencies = [ + "anyhow", + "cosm-orc", + "cosmwasm-std", + "cw-admin-factory", + "cw-utils 1.0.3", + "cw20 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-single 2.5.0", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "env_logger", + "serde", + "serde_json", + "serde_yaml", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] + +[[package]] +name = "btsg-ft-factory" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-token-staked", + "osmosis-std-derive", + "prost 0.12.3", + "prost-derive 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" +dependencies = [ + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "num-traits", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "config" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cosm-orc" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6676a17fddc94aac5fe07bad646d99b7f7cef1f0cc2c74b61af25733cbbb9f08" +dependencies = [ + "config", + "cosm-tome", + "erased-serde", + "log", + "serde", + "serde_json", + "thiserror", + "tokio", +] + +[[package]] +name = "cosm-tome" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "596064e3608349aa302eb68b2df8ed3a66bbb51d9b470dbd9afff70843e44642" +dependencies = [ + "async-trait", + "cosmrs 0.10.0", + "regex", + "schemars", + "serde", + "serde_json", + "thiserror", + "tonic 0.8.3", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20b42021d8488665b1a0d9748f1f81df7235362d194f44481e2e61bf376b77b4" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.23.9", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673d31bd830c0772d78545de20d975129b6ab2f7db4e4e9313c3b8777d319194" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.26.0", + "tonic 0.8.3", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tendermint-proto 0.32.2", + "tonic 0.9.2", +] + +[[package]] +name = "cosmrs" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3903590099dcf1ea580d9353034c9ba1dbf55d1389a5bd2ade98535c3445d1f9" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.14.0", + "ecdsa 0.14.8", + "eyre", + "getrandom", + "k256 0.11.6", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint 0.23.9", + "tendermint-rpc 0.23.9", + "thiserror", +] + +[[package]] +name = "cosmrs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa07096219b1817432b8f1e47c22e928c64bbfd231fc08f0a98f0e7ddd602b7" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.15.0", + "ecdsa 0.14.8", + "eyre", + "getrandom", + "k256 0.11.6", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint 0.26.0", + "tendermint-rpc 0.26.0", + "thiserror", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256 0.13.3", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" +dependencies = [ + "base64 0.21.7", + "bech32", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cosmwasm-storage" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" +dependencies = [ + "cosmwasm-std", + "serde", +] + +[[package]] +name = "cpufeatures" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ct-logs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" +dependencies = [ + "sct", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cw-address-like" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +dependencies = [ + "cosmwasm-std", +] + +[[package]] +name = "cw-admin-factory" +version = "2.5.0" +dependencies = [ + "bech32", + "cosmwasm-schema", + "cosmwasm-std", + "cw-admin-factory", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw4 2.5.0", + "osmosis-test-tube", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64bfeaf55f8dba5646cc3daddce17cd23a60f8e0c3fbacbe6735d287d7a6e33a" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-controllers" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468b8f2696f625c8e15b5468f9420c8eabfaf23cb4fd7e6c660fc7e0cc8d77b8" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-paginate-storage 0.1.0", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw721 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-core-interface" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c93e684945473777ebed2bcaf9f0af2291653f79d5c81774c6826350ba6d88de" +dependencies = [ + "cosmwasm-std", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw-core-interface" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "cosmwasm-std", + "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw2 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw-core-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f20a77489d2dc8a1c12cb0b9671b6cbdca88f12fe65e1a4ee9899490f7669dcc" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-core-macros" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "proc-macro2", + "quote", + "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" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", +] + +[[package]] +name = "cw-fund-distributor" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-voting-cw20-staked", + "thiserror", +] + +[[package]] +name = "cw-hooks" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "097ee97b99ecc90372eac3bcaf698d940a15f806f2ba1e1e901c729f6523e16e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "thiserror", +] + +[[package]] +name = "cw-hooks" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "thiserror", +] + +[[package]] +name = "cw-multi-test" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" +dependencies = [ + "anyhow", + "bech32", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "derivative", + "itertools 0.12.1", + "prost 0.12.3", + "schemars", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cw-ownable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-ownable-derive", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "thiserror", +] + +[[package]] +name = "cw-ownable-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-paginate-storage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b854833e07c557dee02d1b61a21bb0731743bb2e3bbdc3e446a0d8a38af40ec4" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.13.4", + "serde", +] + +[[package]] +name = "cw-paginate-storage" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9740c02c59072ad00de64cc60aae6ca492103dcefc0f7d3cc6f77d768f2ec70" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw-paginate-storage" +version = "2.5.0" +dependencies = [ + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw-payroll-factory" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw-vesting", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", + "wynd-utils", +] + +[[package]] +name = "cw-proposal-single" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6408483e1ac17a7e2b98ef6fa1379776964353bcbf501942d22ee1c1323117" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw3", + "dao-voting 0.1.0", + "indexable-hooks", + "proposal-hooks", + "schemars", + "serde", + "thiserror", + "vote-hooks", +] + +[[package]] +name = "cw-stake-tracker" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-wormhole", +] + +[[package]] +name = "cw-storage-plus" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-storage-plus" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-token-swap" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "thiserror", +] + +[[package]] +name = "cw-tokenfactory-issuer" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-tokenfactory-types", + "cw2 1.1.2", + "dao-interface 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "prost 0.12.3", + "prost-derive 0.12.3", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cw-tokenfactory-types" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "dao-interface 2.5.0", + "osmosis-std", + "osmosis-std-derive", + "prost 0.12.3", + "prost-derive 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "cw-utils" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef842a1792e4285beff7b3b518705f760fa4111dc1e296e53f3e92d1ef7f6220" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 0.16.0", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw-utils" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw-vesting" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-stake-tracker", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw-wormhole", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-testing", + "serde", + "thiserror", + "wynd-utils", +] + +[[package]] +name = "cw-wormhole" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "serde", +] + +[[package]] +name = "cw2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.16.0", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9671d7edef5608acaf5b2f1e473ee3f501eced2cd4f7392e2106c8cf02ba0720" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.11.1", + "schemars", + "serde", +] + +[[package]] +name = "cw20" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw20" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw20-base" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f6fc8c4cd451b418fa4f1ac2ea70595811fa9d8b4033617fe47953d7a93ceb" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "cw2 0.11.1", + "cw20 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-base" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-base" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw20 1.1.2", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-stake" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26f0d51ce27a97b51f66d737183845bc6d82f46f4b246dc959d1265d86906ccc" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20-stake" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 0.2.6", + "dao-hooks 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "cw20-stake-external-rewards" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 0.13.4", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-hooks 2.5.0", + "stake-cw20-external-rewards", + "thiserror", +] + +[[package]] +name = "cw20-stake-reward-distributor" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "stake-cw20-reward-distributor", + "thiserror", +] + +[[package]] +name = "cw20-staked-balance-voting" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf8c2ee92372d35c3a48fd6ddd490a1a4426902748017dd0b7f551d06484e28" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-core-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "schemars", + "serde", +] + +[[package]] +name = "cw4-group" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6c95c89153e7831c8306c8eba40a3daa76f9c7b8f5179dd0b8628aca168ec7a" +dependencies = [ + "cosmwasm-std", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw4 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4-group" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e24a22c3af54c52edf528673b420a67a1648be2c159b8ec778d2fbf543df24b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4-voting" +version = "0.1.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0#e531c760a5d057329afd98d62567aaa4dca2c96f" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-core-macros 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw4 0.13.4", + "cw4-group 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035818368a74c07dd9ed5c5a93340199ba251530162010b9f34c3809e3b97df1" +dependencies = [ + "cosmwasm-std", + "cw-utils 0.13.4", + "schemars", + "serde", +] + +[[package]] +name = "cw721" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 0.16.0", + "schemars", + "serde", +] + +[[package]] +name = "cw721" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw721-base" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.16.0", + "cw-utils 0.16.0", + "cw2 0.16.0", + "cw721 0.16.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721-base" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.16.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721-controllers" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "thiserror", +] + +[[package]] +name = "cw721-roles" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "dao-cw721-extensions", + "dao-testing", + "dao-voting-cw721-staked", + "serde", + "thiserror", +] + +[[package]] +name = "dao-cw721-extensions" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw4 1.1.2", +] + +[[package]] +name = "dao-dao-core" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd16c5f6f2760c66546e1e2f3781106dd796c8920847e78e5984922767cbc68" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-paginate-storage 2.4.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw721 0.18.0", + "dao-dao-macros 2.4.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-dao-core" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c3f39b7aaf9d913d0de8c8742c151011da00662acdbe95c33a5f7bad1b835a" +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 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dao-hooks" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c85abbadefe491d571f709464a8cfd2fb78b63b0cb6e6ef49104df249e28acc" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw4 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-hooks" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.5.0", + "cw4 1.1.2", + "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" +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-migrator" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-core-interface 0.1.0 (git+https://github.com/DA0-DA0/dao-contracts.git?tag=v1.0.0)", + "cw-multi-test", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 0.13.4", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 0.2.6", + "cw20-stake 2.5.0", + "cw20-staked-balance-voting", + "cw4 0.13.4", + "cw4-voting", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approval-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4fe4e5b50b3081272557069dbecaf1e0984d1f2932d2e61418712460f8fd313" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-paginate-storage 2.4.2", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approval-single" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-paginate-storage 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-approval-single 2.4.1", + "dao-pre-propose-base 2.5.0", + "dao-proposal-single 2.4.1", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-approver" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-approval-single 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", +] + +[[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.2", + "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 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 2.5.0", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "dao-pre-propose-multiple" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d6158aeddd2e080c730f1a2ac3814351cbcd38d61c38209dcf1e203d0e554a5" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-pre-propose-multiple" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-multi-test", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-multiple 2.4.1", + "dao-proposal-multiple 2.4.1", + "dao-proposal-multiple 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", +] + +[[package]] +name = "dao-pre-propose-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30f96fb1898f94ea4fe5771f8ab5c2bc6237782e06bb599f070713d11d38c19e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 1.1.2", + "dao-pre-propose-base 2.4.1", + "dao-voting 2.4.1", +] + +[[package]] +name = "dao-pre-propose-single" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.4.1", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.4.1", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-single 2.4.1", + "dao-proposal-single 2.4.1", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.4.1", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.4.1", + "dao-voting-cw4 2.5.0", +] + +[[package]] +name = "dao-proposal-condorcet" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-core 2.5.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw4 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-proposal-hook-counter" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "thiserror", +] + +[[package]] +name = "dao-proposal-incentives" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-proposal-multiple" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51fac47816150063ef09b555f3466f8be99612b76860a20fba7c85bd1854beba" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "dao-dao-macros 2.4.2", + "dao-hooks 2.4.1", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-pre-propose-multiple 2.4.1", + "dao-voting 0.1.0", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-proposal-multiple" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "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", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-multiple 2.5.0", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "rand", + "thiserror", +] + +[[package]] +name = "dao-proposal-single" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce91710cfcff1af520cd0e885eee6972aeefbefc1c9da18349e66ab959269bb" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.4.2", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "dao-dao-macros 2.4.2", + "dao-hooks 2.4.1", + "dao-interface 2.4.1", + "dao-pre-propose-base 2.4.1", + "dao-voting 0.1.0", + "dao-voting 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-proposal-single" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-core", + "cw-denom 2.5.0", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-proposal-single", + "cw-storage-plus 1.2.0", + "cw-utils 0.13.4", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-dao-core 2.5.0", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-base 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-incentives", + "dao-testing", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "thiserror", +] + +[[package]] +name = "dao-proposal-sudo" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-rewards-distributor" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-staked", + "dao-voting-token-staked", + "semver", + "thiserror", +] + +[[package]] +name = "dao-test-custom-factory" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-tokenfactory-issuer", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-testing" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-admin-factory", + "cw-core", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-proposal-single", + "cw-tokenfactory-issuer", + "cw-utils 1.0.3", + "cw-vesting", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw4 1.1.2", + "cw4-group 1.1.2", + "cw721-base 0.18.0", + "cw721-roles", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-multiple 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-condorcet", + "dao-proposal-incentives", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-voting 0.1.0", + "dao-voting 2.5.0", + "dao-voting-cw20-balance", + "dao-voting-cw20-staked", + "dao-voting-cw4 2.5.0", + "dao-voting-cw721-roles", + "dao-voting-cw721-staked", + "dao-voting-onft-staked", + "dao-voting-token-staked", + "osmosis-std", + "osmosis-test-tube", + "rand", + "serde", + "serde_json", + "stake-cw20", +] + +[[package]] +name = "dao-voting" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442d770933e3b3ecab4cfb4d6e9d054082b007d35fda3cf0c3d3ddd1cfa91782" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "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.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-voting" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-denom 2.5.0", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw20-balance" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw20-staked" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw4" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba59e19abd4d51d6c3a37a84fb0c8cfe90e2f2ab551a610ec6749fcd09fc9e86" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-macros 2.4.2", + "dao-interface 2.4.1", + "thiserror", +] + +[[package]] +name = "dao-voting-cw4" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw4-group 1.1.2", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-cw721-roles" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-ownable", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw4 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-controllers", + "cw721-roles", + "dao-cw721-extensions", + "dao-dao-macros 2.5.0", + "dao-interface 2.5.0", + "dao-testing", + "thiserror", +] + +[[package]] +name = "dao-voting-cw721-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-controllers", + "dao-dao-macros 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "serde", + "thiserror", +] + +[[package]] +name = "dao-voting-incentives" +version = "2.5.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-hooks 2.5.0", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20-base 1.1.2", + "dao-dao-core 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-voting 2.5.0", + "thiserror", +] + +[[package]] +name = "dao-voting-onft-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "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 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "omniflix-std", + "osmosis-test-tube", + "prost 0.12.3", + "prost-derive 0.12.3", + "serde", + "thiserror", +] + +[[package]] +name = "dao-voting-token-staked" +version = "2.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers 1.1.2", + "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 2.5.0", + "dao-hooks 2.5.0", + "dao-interface 2.5.0", + "dao-proposal-hook-counter", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-testing", + "dao-voting 2.5.0", + "osmosis-std", + "osmosis-test-tube", + "serde", + "thiserror", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.4.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-proxy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "hyper-rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", + "webpki", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "ct-logs", + "futures-util", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "webpki", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexable-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70922e1e0e68d99ec1a24446c70756cc3e56deaddb505b1f4b43914522d809" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.13.4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "integration-tests" +version = "0.1.0" +dependencies = [ + "anyhow", + "assert_matches", + "cosm-orc", + "cosm-tome", + "cosmos-sdk-proto 0.19.0", + "cosmwasm-std", + "cw-utils 1.0.3", + "cw-vesting", + "cw20 1.1.2", + "cw20-base 1.1.2", + "cw20-stake 2.5.0", + "cw721 0.18.0", + "cw721-base 0.18.0", + "cw721-roles", + "dao-dao-core 2.5.0", + "dao-interface 2.5.0", + "dao-pre-propose-single 2.5.0", + "dao-proposal-single 2.5.0", + "dao-test-custom-factory", + "dao-voting 2.5.0", + "dao-voting-cw20-staked", + "dao-voting-cw721-staked", + "env_logger", + "once_cell", + "rand", + "serde", + "serde_json", + "test-context", +] + +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.156" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +dependencies = [ + "memchr", +] + +[[package]] +name = "omniflix-std" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a662bd7782ef6ad1af3747a2b73d37f8e6a230bb7b1624d96c05b3567501600" +dependencies = [ + "chrono", + "cosmwasm-std", + "omniflix-std-derive", + "prost 0.12.3", + "prost-types 0.12.3", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "omniflix-std-derive" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbd85582e3ef1a23fa7b12e0415ea604260c114e72faf40d829c2c40f1c745e" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "prost-types 0.11.9", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown 0.12.3", +] + +[[package]] +name = "osmosis-std" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7aa053bc3fad557ac90a0377688b400c395e2537f0f1de3293a15cad2e970" +dependencies = [ + "chrono", + "cosmwasm-std", + "osmosis-std-derive", + "prost 0.11.9", + "prost-types 0.11.9", + "schemars", + "serde", + "serde-cw-value", +] + +[[package]] +name = "osmosis-std-derive" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "prost-types 0.11.9", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "osmosis-test-tube" +version = "20.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1534a419d9e2c27b0b4869e68496b92abca93464b82efbdd1f1b43467f2938" +dependencies = [ + "base64 0.21.7", + "bindgen", + "cosmrs 0.9.0", + "cosmwasm-std", + "osmosis-std", + "prost 0.11.9", + "serde", + "serde_json", + "test-tube", + "thiserror", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "pest_meta" +version = "2.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.74", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proposal-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a2f15b848398bad689771b35313c7e7095e772d444e299dbdb54b906691f8a" +dependencies = [ + "cosmwasm-std", + "indexable-hooks", + "schemars", + "serde", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost 0.12.3", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags 1.3.2", + "serde", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-native-certs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" +dependencies = [ + "openssl-probe", + "rustls", + "schannel", + "security-framework", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.74", +] + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.9", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-cw-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.208" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.4.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + +[[package]] +name = "stake-cw20" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfbd45133276dbe4d6588899f4d4d06fdb9f16921fd1394affc0bccc9a5cb0b6" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.11.1", + "cw-storage-plus 0.11.1", + "cw-utils 0.11.1", + "cw2 0.11.1", + "cw20 0.11.1", + "cw20-base 0.11.1", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "stake-cw20-external-rewards" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9bbc1e4b7a932957a05a76921015a849b234c3f25e59fe1fd0d2eab71654bc" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-controllers 0.13.4", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "stake-cw20-reward-distributor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4260ff7aec6dddb43cb5f1104ef5cebe2787853bc83af9172ce5b828b577c4c5" +dependencies = [ + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.13.4", + "cw-utils 0.13.4", + "cw2 0.13.4", + "cw20 0.13.4", + "cw20-base 0.13.4", + "cw20-stake 0.2.6", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tendermint" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467f82178deeebcd357e1273a0c0b77b9a8a0313ef7c07074baebe99d87851f4" +dependencies = [ + "async-trait", + "bytes", + "ed25519", + "ed25519-dalek", + "flex-error", + "futures", + "k256 0.11.6", + "num-traits", + "once_cell", + "prost 0.11.9", + "prost-types 0.11.9", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature 1.6.4", + "subtle", + "subtle-encoding", + "tendermint-proto 0.23.9", + "time", + "zeroize", +] + +[[package]] +name = "tendermint" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa1d2d0ec1b531ba7d196f0dbee5e78ed2a82bfba928e88dff64aeec0b26073" +dependencies = [ + "async-trait", + "bytes", + "ed25519", + "ed25519-dalek", + "flex-error", + "futures", + "k256 0.11.6", + "num-traits", + "once_cell", + "prost 0.11.9", + "prost-types 0.11.9", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature 1.6.4", + "subtle", + "subtle-encoding", + "tendermint-proto 0.26.0", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d42ee0abc27ef5fc34080cce8d43c189950d331631546e7dfb983b6274fa327" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint 0.23.9", + "toml", + "url", +] + +[[package]] +name = "tendermint-config" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202a2f19502c03b353d8157694ed24fbc58c3dd64a92a5b0cb80b79c82af5be4" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint 0.26.0", + "toml", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ce80bf536476db81ecc9ebab834dc329c9c1509a694f211a73858814bfe023" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-proto" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "974d6330a19dfa6720e9f663fc59101d207a817db3f9c730d3f31caaa565b574" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-proto" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.11.9", + "prost-types 0.11.9", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-rpc" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f14aafe3528a0f75e9f3f410b525617b2de16c4b7830a21f717eee62882ec60" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "peg", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle-encoding", + "tendermint 0.23.9", + "tendermint-config 0.23.9", + "tendermint-proto 0.23.9", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tendermint-rpc" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5d87fa5429bd2ee39c4809dd546096daf432de9b71157bc12c182ab5bae7ea7" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "peg", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle", + "subtle-encoding", + "tendermint 0.26.0", + "tendermint-config 0.26.0", + "tendermint-proto 0.26.0", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-context" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6965c21232186af0092233c18030fe607cfc3960dbabb209325272458eeea" +dependencies = [ + "async-trait", + "futures", + "test-context-macros", +] + +[[package]] +name = "test-context-macros" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d506c7664333e246f564949bee4ed39062aa0f11918e6f5a95f553cdad65c274" +dependencies = [ + "quote", + "syn 2.0.74", +] + +[[package]] +name = "test-tube" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e79c7af10967dd3383ee5aae3810637cc3f2fd040f87f862c02151db060628" +dependencies = [ + "base64 0.13.1", + "cosmrs 0.9.0", + "cosmwasm-std", + "osmosis-std", + "prost 0.11.9", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "time" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +dependencies = [ + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "prost-derive 0.11.9", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vote-hooks" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef617ad17edd195f8a3bce72498bfcc406a27cecfc23828f562fa91a3e2fb141" +dependencies = [ + "cosmwasm-std", + "indexable-hooks", + "schemars", + "serde", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.74", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wynd-utils" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa37b3fba808df599acc6f0d7523b465baf47a0b0361867c4f1635eb53f72aa" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] diff --git a/Cargo.toml b/Cargo.toml index 1d98d3a94..d9d399d9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,6 +111,7 @@ dao-pre-propose-multiple = { path = "./contracts/pre-propose/dao-pre-propose-mul dao-pre-propose-single = { path = "./contracts/pre-propose/dao-pre-propose-single", version = "2.5.0" } dao-proposal-condorcet = { path = "./contracts/proposal/dao-proposal-condorcet", version = "2.5.0" } dao-proposal-hook-counter = { path = "./contracts/test/dao-proposal-hook-counter", version = "2.5.0" } +dao-proposal-incentives = { path = "./contracts/external/dao-proposal-incentives", version = "2.5.0" } dao-proposal-multiple = { path = "./contracts/proposal/dao-proposal-multiple", version = "2.5.0" } dao-proposal-single = { path = "./contracts/proposal/dao-proposal-single", version = "2.5.0" } dao-proposal-sudo = { path = "./contracts/test/dao-proposal-sudo", version = "2.5.0" } diff --git a/contracts/dao-dao-core/src/contract.rs b/contracts/dao-dao-core/src/contract.rs index 1ee52a165..8fc57df32 100644 --- a/contracts/dao-dao-core/src/contract.rs +++ b/contracts/dao-dao-core/src/contract.rs @@ -582,6 +582,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalModules { start_after, limit } => { query_proposal_modules(deps, start_after, limit) } + QueryMsg::ProposalModule { address } => query_proposal_module(deps, address), QueryMsg::ProposalModuleCount {} => query_proposal_module_count(deps), QueryMsg::TotalPowerAtHeight { height } => query_total_power_at_height(deps, height), QueryMsg::VotingModule {} => query_voting_module(deps), @@ -598,6 +599,13 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } } +pub fn query_proposal_module(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + let proposal_module = &PROPOSAL_MODULES.load(deps.storage, address)?; + + to_json_binary(&proposal_module) +} + pub fn query_admin(deps: Deps) -> StdResult { let admin = ADMIN.load(deps.storage)?; to_json_binary(&admin) diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index 4de53d38c..ff3827b82 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-proposal-incentives" -authors = ["Jake Hartnell "] +authors = ["Jake Hartnell ", "ismellike"] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } @@ -26,9 +26,15 @@ dao-interface = { workspace = true } dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } +cw-denom = { workspace = true } +cw-ownable = { workspace = true } +cw20 = { workspace = true } [dev-dependencies] cosmwasm-schema = { workspace = true } cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } +dao-testing = { workspace = true } +dao-proposal-single = { workspace = true, features = ["library"] } +cw-hooks = { workspace = true } \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 7fea7973b..106344544 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -5,10 +5,6 @@ Allows for DAOs to offer incentives for making successful proposals. -To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When someone successfully passes a proposal the specified rewards are automatically paid out. +To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module, and the DAO must be the `owner` of this contract. When someone successfully passes a proposal the specified rewards are automatically paid out. -## TODO -- [ ] Unit and Integration tests with a full DAO -- [ ] Support Cw20 -- [ ] Use `cw-ownable` to configure a contract owner who can update the proposal incentives config. -- [ ] Add more info to the readme and delete this TODO section +The incentives can be configured as native or cw20 tokens, and the award is determined by the configuration at the passed proposal's `start_time`. \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/src/contract.rs b/contracts/external/dao-proposal-incentives/src/contract.rs index 5e7cabcea..c8fc6ff73 100644 --- a/contracts/external/dao-proposal-incentives/src/contract.rs +++ b/contracts/external/dao-proposal-incentives/src/contract.rs @@ -1,51 +1,39 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, - SubMsg, -}; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; -use cw_utils::must_pay; -use dao_hooks::proposal::ProposalHookMsg; -use dao_voting::status::Status; +use cw_ownable::get_ownership; -use crate::error::ContractError; -use crate::msg::{ConfigResponse, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{DAO, PROPOSAL_INCENTIVES}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use crate::state::PROPOSAL_INCENTIVES; +use crate::{execute, query, ContractError}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub const REPLY_PROPOSAL_HOOK_ID: u64 = 1; - #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save DAO, assumes the sender is the DAO - DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + // Save ownership + let ownership = cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; - // Save proposal incentives config - PROPOSAL_INCENTIVES.save(deps.storage, &msg.proposal_incentives)?; + // Validate proposal incentives + let proposal_incentives = msg.proposal_incentives.into_checked(deps.as_ref())?; - // Check initial deposit contains enough funds to pay out rewards - // for at least one proposal - let amount = must_pay(&info, &msg.proposal_incentives.rewards_per_proposal.denom)?; - if amount < msg.proposal_incentives.rewards_per_proposal.amount { - return Err(ContractError::InsufficientInitialDeposit { - expected: msg.proposal_incentives.rewards_per_proposal.amount, - actual: amount, - }); - }; + // Save proposal incentives config + PROPOSAL_INCENTIVES.save(deps.storage, &proposal_incentives, env.block.height)?; Ok(Response::new() .add_attribute("method", "instantiate") - .add_attribute("creator", info.sender)) + .add_attribute("creator", info.sender) + .add_attributes(ownership.into_attributes()) + .add_attributes(proposal_incentives.into_attributes())) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -56,79 +44,30 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::ProposalHook(msg) => execute_proposal_hook(deps, env, info, msg), - } -} - -// TODO support cw20 tokens -pub fn execute_proposal_hook( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: ProposalHookMsg, -) -> Result { - let mut payout_msgs: Vec = vec![]; - - // Check prop status and type of hook - match msg { - ProposalHookMsg::ProposalStatusChanged { new_status, .. } => { - // If prop status is success, add message to pay out rewards - // Otherwise, do nothing - if new_status == Status::Passed.to_string() { - // Load proposal incentives config - let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; - - // We handle payout messages in a SubMsg so the error be caught - // if need be. This is to prevent running out of funds locking the DAO. - payout_msgs.push(SubMsg::reply_on_error( - BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![proposal_incentives.rewards_per_proposal], - }, - REPLY_PROPOSAL_HOOK_ID, - )); - } + ExecuteMsg::ProposalHook(msg) => execute::proposal_hook(deps, env, info, msg), + ExecuteMsg::UpdateOwnership(action) => execute::update_ownership(deps, env, info, action), + ExecuteMsg::UpdateProposalIncentives { + proposal_incentives, + } => execute::update_proposal_incentives(deps, env, info, proposal_incentives), + ExecuteMsg::Receive(cw20_receive_msg) => { + execute::receive_cw20(deps, env, info, cw20_receive_msg) } - _ => {} } - - Ok(Response::default() - .add_attribute("action", "proposal_hook") - .add_submessages(payout_msgs)) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => query_config(deps), + QueryMsg::ProposalIncentives { height } => { + to_json_binary(&query::proposal_incentives(deps, height)?) + } + QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), } } -pub fn query_config(deps: Deps) -> StdResult { - let dao = DAO.load(deps.storage)?; - let proposal_incentives = PROPOSAL_INCENTIVES.load(deps.storage)?; - - to_json_binary(&ConfigResponse { - dao: dao.to_string(), - proposal_incentives, - }) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { // Set contract to version to latest set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) } - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { - match msg.id { - REPLY_PROPOSAL_HOOK_ID => { - // If an error occurred with payout, we still return an ok response - // because we don't want to fail the proposal hook and lock the DAO. - Ok(Response::default()) - } - _ => Err(ContractError::UnknownReplyID {}), - } -} diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index 69d218ddc..ee3ba8822 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -1,4 +1,6 @@ -use cosmwasm_std::{StdError, Uint128}; +use cosmwasm_std::StdError; +use cw_denom::DenomError; +use cw_ownable::OwnershipError; use cw_utils::{ParseReplyError, PaymentError}; use thiserror::Error; @@ -10,15 +12,21 @@ pub enum ContractError { #[error("{0}")] PaymentError(#[from] PaymentError), - #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] - InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + #[error("{0}")] + DenomError(#[from] DenomError), #[error("{0}")] ParseReplyError(#[from] ParseReplyError), + #[error("{0}")] + OwnershipError(#[from] OwnershipError), + #[error("Unauthorized")] Unauthorized {}, #[error("An unknown reply ID was received.")] UnknownReplyID {}, + + #[error("No reward per proposal given")] + NoRewardPerProposal {}, } diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs new file mode 100644 index 000000000..b7d30dfe4 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -0,0 +1,112 @@ +use cosmwasm_std::{Attribute, CosmosMsg, DepsMut, Env, MessageInfo, Response}; +use cw20::Cw20ReceiveMsg; +use cw_ownable::{assert_owner, get_ownership}; +use dao_hooks::proposal::ProposalHookMsg; +use dao_interface::{proposal::GenericProposalInfo, state::ProposalModule}; +use dao_voting::status::Status; + +use crate::{msg::ProposalIncentivesUnchecked, state::PROPOSAL_INCENTIVES, ContractError}; + +pub fn proposal_hook( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ProposalHookMsg, +) -> Result { + let mut msgs: Vec = vec![]; + let mut attrs: Vec = vec![]; + + // Get ownership + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + // Validate the message is coming from a proposal module of the owner (DAO) + deps.querier.query_wasm_smart::( + owner, + &dao_interface::msg::QueryMsg::ProposalModule { + address: info.sender.to_string(), + }, + )?; + + // Check prop status and type of hook + match msg { + ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } => { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Query for the proposal + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender, + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, + )?; + + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, proposal_info.start_height)?; + + // Append the message if found + if let Some(proposal_incentives) = proposal_incentives { + msgs.push(proposal_incentives.denom.get_transfer_to_message( + &proposal_info.proposer, + proposal_incentives.rewards_per_proposal, + )?); + attrs = proposal_incentives.into_attributes(); + attrs.push(Attribute { + key: "proposer".to_string(), + value: proposal_info.proposer.to_string(), + }); + } + } + } + _ => {} + } + } + + Ok(Response::default() + .add_attribute("action", "proposal_hook") + .add_attributes(attrs) + .add_messages(msgs)) +} + +pub fn update_ownership( + deps: DepsMut, + env: Env, + info: MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + + Ok(Response::new() + .add_attribute("action", "update_ownership") + .add_attributes(ownership.into_attributes())) +} + +pub fn update_proposal_incentives( + deps: DepsMut, + env: Env, + info: MessageInfo, + proposal_incentives: ProposalIncentivesUnchecked, +) -> Result { + assert_owner(deps.storage, &info.sender)?; + + // Validate proposal incentives + let proposal_incentives = proposal_incentives.into_checked(deps.as_ref())?; + + // Save the new proposal incentives + PROPOSAL_INCENTIVES.save(deps.storage, &proposal_incentives, env.block.height)?; + + Ok(Response::new() + .add_attribute("action", "update_proposal_incentives") + .add_attributes(proposal_incentives.into_attributes())) +} + +pub fn receive_cw20( + _deps: DepsMut, + _env: Env, + info: MessageInfo, + _cw20_receive_msg: Cw20ReceiveMsg, +) -> Result { + Ok(Response::new() + .add_attribute("action", "receive_cw20") + .add_attribute("cw20", info.sender)) +} diff --git a/contracts/external/dao-proposal-incentives/src/helpers.rs b/contracts/external/dao-proposal-incentives/src/helpers.rs new file mode 100644 index 000000000..fa3932a88 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/helpers.rs @@ -0,0 +1,31 @@ +use cosmwasm_std::{Attribute, Deps}; + +use crate::{msg::ProposalIncentivesUnchecked, state::ProposalIncentives, ContractError}; + +impl ProposalIncentivesUnchecked { + pub fn into_checked(self, deps: Deps) -> Result { + if self.rewards_per_proposal.is_zero() { + return Err(ContractError::NoRewardPerProposal {}); + } + + Ok(ProposalIncentives { + rewards_per_proposal: self.rewards_per_proposal, + denom: self.denom.into_checked(deps)?, + }) + } +} + +impl ProposalIncentives { + pub fn into_attributes(&self) -> Vec { + vec![ + Attribute { + key: "reward_per_proposal".to_string(), + value: self.rewards_per_proposal.to_string(), + }, + Attribute { + key: "denom".to_string(), + value: self.denom.to_string(), + }, + ] + } +} diff --git a/contracts/external/dao-proposal-incentives/src/lib.rs b/contracts/external/dao-proposal-incentives/src/lib.rs index d1800adbc..9bb953dba 100644 --- a/contracts/external/dao-proposal-incentives/src/lib.rs +++ b/contracts/external/dao-proposal-incentives/src/lib.rs @@ -2,7 +2,10 @@ pub mod contract; mod error; +pub mod execute; +mod helpers; pub mod msg; +pub mod query; pub mod state; #[cfg(test)] diff --git a/contracts/external/dao-proposal-incentives/src/msg.rs b/contracts/external/dao-proposal-incentives/src/msg.rs index d3290bbde..cb6f74186 100644 --- a/contracts/external/dao-proposal-incentives/src/msg.rs +++ b/contracts/external/dao-proposal-incentives/src/msg.rs @@ -1,37 +1,47 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Uint128; +use cw20::Cw20ReceiveMsg; +use cw_denom::UncheckedDenom; +use cw_ownable::cw_ownable_query; use dao_hooks::proposal::ProposalHookMsg; use crate::state::ProposalIncentives; #[cw_serde] pub struct InstantiateMsg { - /// DAO address - pub dao: String, + /// The contract's owner using cw-ownable + pub owner: String, /// Rewards to pay out for successful proposals. - pub proposal_incentives: ProposalIncentives, + pub proposal_incentives: ProposalIncentivesUnchecked, } #[cw_serde] pub enum ExecuteMsg { /// Fires when a new proposal status has changed. ProposalHook(ProposalHookMsg), + UpdateOwnership(cw_ownable::Action), + UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked, + }, + Receive(Cw20ReceiveMsg), } +#[cw_ownable_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - /// Returns the config. - #[returns(ConfigResponse)] - Config {}, + /// Returns the proposal incentives + #[returns(ProposalIncentives)] + ProposalIncentives { height: Option }, } #[cw_serde] -pub struct ConfigResponse { - /// DAO address - pub dao: String, - /// Rewards to pay out for successful proposals. - pub proposal_incentives: ProposalIncentives, +pub struct ProposalIncentivesUnchecked { + pub rewards_per_proposal: Uint128, + pub denom: UncheckedDenom, } #[cw_serde] -pub struct MigrateMsg {} +pub enum MigrateMsg { + FromCompatible {}, +} diff --git a/contracts/external/dao-proposal-incentives/src/query.rs b/contracts/external/dao-proposal-incentives/src/query.rs new file mode 100644 index 000000000..5e53dceec --- /dev/null +++ b/contracts/external/dao-proposal-incentives/src/query.rs @@ -0,0 +1,14 @@ +use cosmwasm_std::{Deps, StdResult}; + +use crate::state::{ProposalIncentives, PROPOSAL_INCENTIVES}; + +pub fn proposal_incentives(deps: Deps, height: Option) -> StdResult { + match height { + Some(height) => PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, height)? + .ok_or(cosmwasm_std::StdError::NotFound { + kind: "Proposal Incentives".to_string(), + }), + None => PROPOSAL_INCENTIVES.load(deps.storage), + } +} diff --git a/contracts/external/dao-proposal-incentives/src/state.rs b/contracts/external/dao-proposal-incentives/src/state.rs index ee7c7c0af..4dffda609 100644 --- a/contracts/external/dao-proposal-incentives/src/state.rs +++ b/contracts/external/dao-proposal-incentives/src/state.rs @@ -1,16 +1,20 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin}; -use cw_storage_plus::Item; - -/// The address of the DAO this contract serves -pub const DAO: Item = Item::new("dao"); +use cosmwasm_std::Uint128; +use cw_denom::CheckedDenom; +use cw_storage_plus::{SnapshotItem, Strategy}; /// Incentives for passing successful proposals #[cw_serde] pub struct ProposalIncentives { /// The rewards to pay out per successful proposal. - pub rewards_per_proposal: Coin, + pub rewards_per_proposal: Uint128, + pub denom: CheckedDenom, } /// Holds ProposalIncentives state -pub const PROPOSAL_INCENTIVES: Item = Item::new("proposal_incentives"); +pub const PROPOSAL_INCENTIVES: SnapshotItem = SnapshotItem::new( + "proposal_incentives", + "proposal_incentives__check", + "proposal_incentives__change", + Strategy::EveryBlock, +); diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 3bee180ee..340952ab1 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -1,30 +1,41 @@ use std::vec; use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, + testing::{mock_dependencies, mock_env}, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Uint128, WasmMsg, }; -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; -use dao_interface::state::{Admin, ModuleInstantiateInfo}; +use cw20::Cw20Coin; +use cw_denom::{CheckedDenom, UncheckedDenom}; +use cw_multi_test::{ + error::AnyResult, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, +}; +use cw_ownable::Ownership; +use dao_testing::{ + contracts::{dao_proposal_incentives_contract, proposal_single_contract}, + helpers::instantiate_with_cw4_groups_governance, +}; +use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; use crate::{ - contract::instantiate, - contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, - msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, + contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, ProposalIncentivesUnchecked, QueryMsg}, + state::ProposalIncentives, }; -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) +const ADMIN: &str = "admin"; +const ADDR1: &str = "addr1"; +const DENOM: &str = "juno"; + +struct Context { + app: App, + cw20_addr: Addr, + proposal_single_addr: Addr, + dao_addr: Addr, + dao_proposal_incentives_code_id: u64, } -fn cw20_contract() -> Box> { +fn cw20_base_contract() -> Box> { let contract = ContractWrapper::new( cw20_base::contract::execute, cw20_base::contract::instantiate, @@ -33,135 +44,414 @@ fn cw20_contract() -> Box> { Box::new(contract) } -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} +fn get_context() -> Context { + // Set up app with native balances + let mut app = AppBuilder::default().build(|router, _, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked(ADMIN), + vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + }); -#[test] -pub fn test_set_admin() { - let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); - let cw20_instantiate = cw20_base::msg::InstantiateMsg { - name: "DAO".to_string(), - symbol: "DAO".to_string(), - decimals: 6, - initial_balances: vec![], - mint: None, - marketing: None, - }; - - let instantiate = InstantiateMsg {}; - let factory_addr = app + // Set up cw20 with balances + let cw20_code_id = app.store_code(cw20_base_contract()); + let cw20_addr = app .instantiate_contract( - code_id, - Addr::unchecked("CREATOR"), - &instantiate, + cw20_code_id, + Addr::unchecked(ADMIN), + &cw20_base::msg::InstantiateMsg { + name: "cw20 token".to_string(), + symbol: "cwtoken".to_string(), + decimals: 6, + initial_balances: vec![Cw20Coin { + address: ADMIN.to_string(), + amount: Uint128::new(1000), + }], + mint: None, + marketing: None, + }, &[], - "cw-admin-factory", + "cw20-base", None, ) .unwrap(); - // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); - let instantiate_core = dao_interface::msg::InstantiateMsg { - dao_uri: None, - admin: None, - name: "DAO DAO".to_string(), - description: "A DAO that builds DAOs.".to_string(), - image_url: None, - automatically_add_cw20s: true, - automatically_add_cw721s: true, - voting_module_instantiate_info: ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "voting module".to_string(), - }, - proposal_modules_instantiate_info: vec![ - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module".to_string(), + // Set up dao + let proposal_single_code_id = app.store_code(proposal_single_contract()); + let dao_addr = instantiate_with_cw4_groups_governance( + &mut app, + proposal_single_code_id, + to_json_binary(&dao_proposal_single::msg::InstantiateMsg { + threshold: Threshold::AbsolutePercentage { + percentage: dao_voting::threshold::PercentageThreshold::Majority {}, }, - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module 2".to_string(), + max_voting_period: cw_utils::Duration::Height(10u64), + min_voting_period: None, + only_members_execute: false, + allow_revoting: false, + pre_propose_info: dao_voting::pre_propose::PreProposeInfo::AnyoneMayPropose {}, + close_proposal_on_execution_failure: true, + veto: None, + }) + .unwrap(), + Some(vec![Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::one(), + }]), + ); + + // Get proposal single addr + let proposal_modules: Vec = app + .wrap() + .query_wasm_smart( + dao_addr.clone(), + &dao_interface::msg::QueryMsg::ProposalModules { + start_after: None, + limit: Some(1u32), }, - ], - initial_items: None, - }; + ) + .unwrap(); + assert!(!proposal_modules.is_empty()); + let proposal_single_addr = proposal_modules.first().unwrap().address.clone(); + + // Set up dao proposal incentives code id + let dao_proposal_incentives_code_id = app.store_code(dao_proposal_incentives_contract()); + + Context { + app, + cw20_addr, + dao_addr, + dao_proposal_incentives_code_id, + proposal_single_addr, + } +} + +fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> AnyResult { + context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &vec![], + ) +} - let res: AppResponse = app +fn execute_proposal(context: &mut Context, proposal_id: u64) { + context + .app .execute_contract( - Addr::unchecked("CREATOR"), - factory_addr, - &ExecuteMsg::InstantiateContractWithSelfAdmin { - instantiate_msg: to_json_binary(&instantiate_core).unwrap(), - code_id: cw_core_code_id, - label: "my contract".to_string(), + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Execute { proposal_id }, + &vec![], + ) + .unwrap(); +} + +#[test] +pub fn test_setup_native() { + let mut context = get_context(); + + // Cannot instantiate with 0 due + let result = context.app.instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: ADMIN.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::zero(), + denom: UncheckedDenom::Native(DENOM.to_string()), }, - &[], + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ); + assert!(result.is_err()); + + // Can instantiate with some due + let result = context.app.instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: ADMIN.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::new(1000), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ); + assert!(result.is_ok()); + let dao_proposal_incentives_addr = result.unwrap(); + + // Ensure owner was set on init + let ownership: Ownership = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::Ownership {}, + ) + .unwrap(); + + assert_eq!(ownership.owner, Some(ADMIN.to_string())); + + // Ensure proposal incentives was set + let proposal_incentives: ProposalIncentives = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::ProposalIncentives { height: None }, ) .unwrap(); + assert_eq!( + proposal_incentives, + ProposalIncentives { + rewards_per_proposal: Uint128::new(1000), + denom: CheckedDenom::Native(DENOM.to_string()) + } + ); - // Get the core address from the instantiate event - let instantiate_event = &res.events[2]; - assert_eq!(instantiate_event.ty, "instantiate"); - let core_addr = instantiate_event.attributes[0].value.clone(); + // Cannot update rewards to zero + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::zero(), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &[], + ); + assert!(result.is_err()); - // Check that admin of core address is itself - let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); - assert_eq!(contract_info.admin, Some(core_addr)) + // Cannot update unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::one(), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &[], + ); + assert!(result.is_err()); + + // Can update rewards + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::UpdateProposalIncentives { + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::one(), + denom: UncheckedDenom::Cw20(context.cw20_addr.to_string()), + }, + }, + &[], + ); + assert!(result.is_ok()); + + // Ensure proposal incentives was updated + let proposal_incentives: ProposalIncentives = context + .app + .wrap() + .query_wasm_smart( + dao_proposal_incentives_addr.clone(), + &QueryMsg::ProposalIncentives { height: None }, + ) + .unwrap(); + assert_eq!( + proposal_incentives, + ProposalIncentives { + rewards_per_proposal: Uint128::one(), + denom: CheckedDenom::Cw20(context.cw20_addr.clone()), + } + ); } #[test] -pub fn test_set_admin_mock() { - let mut deps = mock_dependencies(); - // Instantiate factory contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info("creator", &[]); - let env = mock_env(); - instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); - let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; - let reply_msg: Reply = Reply { - id: INSTANTIATE_CONTRACT_REPLY_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: (Some(Binary(bytes))), - }), - }; - - let res = reply(deps.as_mut(), env, reply_msg).unwrap(); - assert_eq!(res.attributes.len(), 1); +pub fn test_hook() { + let mut context = get_context(); + + // Create the proposal incentives contract + let dao_proposal_incentives_addr = context + .app + .instantiate_contract( + context.dao_proposal_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::new(1000), + denom: UncheckedDenom::Native(DENOM.to_string()), + }, + }, + &vec![], + "dao_proposal_incentives".to_string(), + None, + ) + .unwrap(); + context.app.update_block(|x| x.height += 10); + + // Execute fails - unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &ExecuteMsg::ProposalHook( + dao_hooks::proposal::ProposalHookMsg::ProposalStatusChanged { + id: 1u64, + old_status: "open".to_string(), + new_status: "passed".to_string(), + }, + ), + &[], + ); + assert!(result.is_err()); + + // Fund the incentives contract for 1 reward + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_proposal_incentives_addr.clone(), + &vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + + // Fund the incentives contract with cw20 as well to show cw20 support + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + context.cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::Send { + contract: dao_proposal_incentives_addr.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }, + &[], + ); + assert!(result.is_ok()); + + // Propose adding a hook + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add proposal hook".to_string(), + description: "Adding a proposal hook to test the dao_proposal_incentives contract" + .to_string(), + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { + address: dao_proposal_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + })], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Vote and execute the proposal to add the proposal hook + vote_yes_on_proposal(&mut context, 1u64).unwrap(); + execute_proposal(&mut context, 1u64); + + // Query for the newly-established hook + let result: cw_hooks::HooksResponse = context + .app + .wrap() + .query_wasm_smart( + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::QueryMsg::ProposalHooks {}, + ) + .unwrap(); + assert!(result + .hooks + .contains(&dao_proposal_incentives_addr.to_string())); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Assert that the proposal hook's execution has sent funds to proposer + let result = vote_yes_on_proposal(&mut context, 2u64); + assert!(result.is_ok()); + let balance = context.app.wrap().query_balance(ADDR1, DENOM).unwrap(); assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::UpdateAdmin { - contract_addr: "contract2".to_string(), - admin: "contract2".to_string() - }) - ) + balance, + Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000) + } + ); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &vec![], + ) + .unwrap(); + + // Assert that the proposal hook's failure still allows completion + // The hook is attempting to send funds when it has run out of funds + let result = vote_yes_on_proposal(&mut context, 3u64); + assert!(result.is_ok()); + assert!(result.unwrap().events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_proposal_hook" + && y.value == format!("{0}:0", dao_proposal_incentives_addr)))); } #[test] pub fn test_migrate_update_version() { let mut deps = mock_dependencies(); cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg::FromCompatible {}).unwrap(); let version = cw2::get_contract_version(&deps.storage).unwrap(); assert_eq!(version.version, CONTRACT_VERSION); assert_eq!(version.contract, CONTRACT_NAME); diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index d80c6b322..a64900db1 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -32,3 +32,4 @@ cosmwasm-schema = { workspace = true } cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } +cw-hooks = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 28ff99777..8ee17afc0 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; use cw_utils::must_pay; use dao_hooks::vote::VoteHookMsg; diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index 3bee180ee..8b1378917 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -1,168 +1 @@ -use std::vec; -use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - to_json_binary, Addr, Binary, Empty, Reply, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, -}; - -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; -use dao_interface::state::{Admin, ModuleInstantiateInfo}; - -use crate::{ - contract::instantiate, - contract::{migrate, reply, CONTRACT_NAME, CONTRACT_VERSION, INSTANTIATE_CONTRACT_REPLY_ID}, - msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}, -}; - -fn factory_contract() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ) - .with_reply(crate::contract::reply); - Box::new(contract) -} - -fn cw20_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - -fn cw_core_contract() -> Box> { - let contract = ContractWrapper::new( - dao_dao_core::contract::execute, - dao_dao_core::contract::instantiate, - dao_dao_core::contract::query, - ) - .with_reply(dao_dao_core::contract::reply) - .with_migrate(dao_dao_core::contract::migrate); - Box::new(contract) -} - -#[test] -pub fn test_set_admin() { - let mut app = App::default(); - let code_id = app.store_code(factory_contract()); - let cw20_code_id = app.store_code(cw20_contract()); - let cw20_instantiate = cw20_base::msg::InstantiateMsg { - name: "DAO".to_string(), - symbol: "DAO".to_string(), - decimals: 6, - initial_balances: vec![], - mint: None, - marketing: None, - }; - - let instantiate = InstantiateMsg {}; - let factory_addr = app - .instantiate_contract( - code_id, - Addr::unchecked("CREATOR"), - &instantiate, - &[], - "cw-admin-factory", - None, - ) - .unwrap(); - - // Instantiate core contract using factory. - let cw_core_code_id = app.store_code(cw_core_contract()); - let instantiate_core = dao_interface::msg::InstantiateMsg { - dao_uri: None, - admin: None, - name: "DAO DAO".to_string(), - description: "A DAO that builds DAOs.".to_string(), - image_url: None, - automatically_add_cw20s: true, - automatically_add_cw721s: true, - voting_module_instantiate_info: ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "voting module".to_string(), - }, - proposal_modules_instantiate_info: vec![ - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module".to_string(), - }, - ModuleInstantiateInfo { - code_id: cw20_code_id, - msg: to_json_binary(&cw20_instantiate).unwrap(), - admin: Some(Admin::CoreModule {}), - funds: vec![], - label: "prop module 2".to_string(), - }, - ], - initial_items: None, - }; - - let res: AppResponse = app - .execute_contract( - Addr::unchecked("CREATOR"), - factory_addr, - &ExecuteMsg::InstantiateContractWithSelfAdmin { - instantiate_msg: to_json_binary(&instantiate_core).unwrap(), - code_id: cw_core_code_id, - label: "my contract".to_string(), - }, - &[], - ) - .unwrap(); - - // Get the core address from the instantiate event - let instantiate_event = &res.events[2]; - assert_eq!(instantiate_event.ty, "instantiate"); - let core_addr = instantiate_event.attributes[0].value.clone(); - - // Check that admin of core address is itself - let contract_info = app.wrap().query_wasm_contract_info(&core_addr).unwrap(); - assert_eq!(contract_info.admin, Some(core_addr)) -} - -#[test] -pub fn test_set_admin_mock() { - let mut deps = mock_dependencies(); - // Instantiate factory contract - let instantiate_msg = InstantiateMsg {}; - let info = mock_info("creator", &[]); - let env = mock_env(); - instantiate(deps.as_mut(), env.clone(), info, instantiate_msg).unwrap(); - let bytes = vec![10, 9, 99, 111, 110, 116, 114, 97, 99, 116, 50]; - let reply_msg: Reply = Reply { - id: INSTANTIATE_CONTRACT_REPLY_ID, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: (Some(Binary(bytes))), - }), - }; - - let res = reply(deps.as_mut(), env, reply_msg).unwrap(); - assert_eq!(res.attributes.len(), 1); - assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::UpdateAdmin { - contract_addr: "contract2".to_string(), - admin: "contract2".to_string() - }) - ) -} - -#[test] -pub fn test_migrate_update_version() { - let mut deps = mock_dependencies(); - cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); - let version = cw2::get_contract_version(&deps.storage).unwrap(); - assert_eq!(version.version, CONTRACT_VERSION); - assert_eq!(version.contract, CONTRACT_NAME); -} diff --git a/contracts/proposal/dao-proposal-condorcet/src/contract.rs b/contracts/proposal/dao-proposal-condorcet/src/contract.rs index 3d3785002..903a1e3d9 100644 --- a/contracts/proposal/dao-proposal-condorcet/src/contract.rs +++ b/contracts/proposal/dao-proposal-condorcet/src/contract.rs @@ -260,6 +260,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::Info {} => to_json_binary(&dao_interface::voting::InfoResponse { info: cw2::get_contract_version(deps.storage)?, }), + QueryMsg::GenericProposalInfo { proposal_id: _ } => unimplemented!(), } } diff --git a/contracts/proposal/dao-proposal-multiple/src/contract.rs b/contracts/proposal/dao-proposal-multiple/src/contract.rs index 6fc42f899..7f8e5e708 100644 --- a/contracts/proposal/dao-proposal-multiple/src/contract.rs +++ b/contracts/proposal/dao-proposal-multiple/src/contract.rs @@ -865,9 +865,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalHooks {} => to_json_binary(&PROPOSAL_HOOKS.query_hooks(deps)?), QueryMsg::VoteHooks {} => to_json_binary(&VOTE_HOOKS.query_hooks(deps)?), QueryMsg::Dao {} => query_dao(deps), + QueryMsg::GenericProposalInfo { proposal_id } => { + query_generic_proposal_info(deps, proposal_id) + } } } +pub fn query_generic_proposal_info(deps: Deps, id: u64) -> StdResult { + to_json_binary(&PROPOSALS.load(deps.storage, id)?.into_generic()) +} + pub fn query_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; to_json_binary(&config) diff --git a/contracts/proposal/dao-proposal-multiple/src/proposal.rs b/contracts/proposal/dao-proposal-multiple/src/proposal.rs index 454a60762..5d760b477 100644 --- a/contracts/proposal/dao-proposal-multiple/src/proposal.rs +++ b/contracts/proposal/dao-proposal-multiple/src/proposal.rs @@ -3,6 +3,7 @@ use std::ops::Add; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, StdError, StdResult, Uint128}; use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; use dao_voting::{ multiple_choice::{ CheckedMultipleChoiceOption, MultipleChoiceOptionType, MultipleChoiceVotes, VotingStrategy, @@ -283,6 +284,13 @@ impl MultipleChoiceProposal { } Ok(false) } + + pub fn into_generic(self) -> GenericProposalInfo { + GenericProposalInfo { + proposer: self.proposer, + start_height: self.start_height, + } + } } #[cfg(test)] diff --git a/contracts/proposal/dao-proposal-single/Cargo.toml b/contracts/proposal/dao-proposal-single/Cargo.toml index 06170dd00..6bc126fa9 100644 --- a/contracts/proposal/dao-proposal-single/Cargo.toml +++ b/contracts/proposal/dao-proposal-single/Cargo.toml @@ -54,3 +54,4 @@ cw721-base = { workspace = true } cw4 = { workspace = true } cw4-group = { workspace = true } cw-core-v1 = { workspace = true, features = ["library"] } +dao-proposal-incentives = { workspace = true } diff --git a/contracts/proposal/dao-proposal-single/src/contract.rs b/contracts/proposal/dao-proposal-single/src/contract.rs index 1943081d1..f2329ecc6 100644 --- a/contracts/proposal/dao-proposal-single/src/contract.rs +++ b/contracts/proposal/dao-proposal-single/src/contract.rs @@ -845,9 +845,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ProposalCreationPolicy {} => query_creation_policy(deps), QueryMsg::ProposalHooks {} => to_json_binary(&PROPOSAL_HOOKS.query_hooks(deps)?), QueryMsg::VoteHooks {} => to_json_binary(&VOTE_HOOKS.query_hooks(deps)?), + QueryMsg::GenericProposalInfo { proposal_id } => { + query_generic_proposal_info(deps, proposal_id) + } } } +pub fn query_generic_proposal_info(deps: Deps, id: u64) -> StdResult { + to_json_binary(&PROPOSALS.load(deps.storage, id)?.into_generic()) +} + pub fn query_config(deps: Deps) -> StdResult { let config = CONFIG.load(deps.storage)?; to_json_binary(&config) diff --git a/contracts/proposal/dao-proposal-single/src/proposal.rs b/contracts/proposal/dao-proposal-single/src/proposal.rs index a597f3754..0cef6eec3 100644 --- a/contracts/proposal/dao-proposal-single/src/proposal.rs +++ b/contracts/proposal/dao-proposal-single/src/proposal.rs @@ -5,6 +5,7 @@ use crate::state::PROPOSAL_COUNT; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, BlockInfo, CosmosMsg, Decimal, Empty, StdResult, Storage, Uint128}; use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; use dao_voting::status::Status; use dao_voting::threshold::{PercentageThreshold, Threshold}; use dao_voting::veto::VetoConfig; @@ -270,6 +271,13 @@ impl SingleChoiceProposal { } } } + + pub fn into_generic(self) -> GenericProposalInfo { + GenericProposalInfo { + proposer: self.proposer, + start_height: self.start_height, + } + } } #[cfg(test)] diff --git a/packages/dao-dao-macros/src/lib.rs b/packages/dao-dao-macros/src/lib.rs index 48611fddf..8b45a9a6e 100644 --- a/packages/dao-dao-macros/src/lib.rs +++ b/packages/dao-dao-macros/src/lib.rs @@ -392,6 +392,9 @@ pub fn proposal_module_query(metadata: TokenStream, input: TokenStream) -> Token /// next proposal created. #[returns(::std::primitive::u64)] NextProposalId {}, + /// Returns generic proposal information + #[returns(dao_interface::proposal::GenericProposalInfo)] + GenericProposalInfo { proposal_id: ::std::primitive::u64 }, } } .into(), diff --git a/packages/dao-dao-macros/tests/govmod.rs b/packages/dao-dao-macros/tests/govmod.rs index f69d281cb..5c437de73 100644 --- a/packages/dao-dao-macros/tests/govmod.rs +++ b/packages/dao-dao-macros/tests/govmod.rs @@ -24,5 +24,6 @@ fn proposal_module_query_derive() { Test::Foo | Test::Bar(_) | Test::Baz { .. } | Test::Dao {} => "yay", Test::Info {} => "yay", Test::NextProposalId {} => "yay", + Test::GenericProposalInfo { proposal_id: _ } => "yay", }; } diff --git a/packages/dao-hooks/src/proposal.rs b/packages/dao-hooks/src/proposal.rs index c98cfdc45..20f915d4a 100644 --- a/packages/dao-hooks/src/proposal.rs +++ b/packages/dao-hooks/src/proposal.rs @@ -8,7 +8,7 @@ use dao_voting::{ }; /// An enum representing proposal hook messages. -/// Either a new propsoal hook, fired when a new proposal is created, +/// Either a new proposal hook, fired when a new proposal is created, /// or a proposal status hook, fired when a proposal changes status. #[cw_serde] pub enum ProposalHookMsg { diff --git a/packages/dao-interface/src/msg.rs b/packages/dao-interface/src/msg.rs index 969288433..efdc777ab 100644 --- a/packages/dao-interface/src/msg.rs +++ b/packages/dao-interface/src/msg.rs @@ -193,6 +193,9 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + // Gets a proposal module + #[returns(crate::state::ProposalModule)] + ProposalModule { address: String }, /// Gets the active proposal modules associated with the /// contract. #[returns(Vec)] diff --git a/packages/dao-interface/src/proposal.rs b/packages/dao-interface/src/proposal.rs index 77076d5c2..f71868986 100644 --- a/packages/dao-interface/src/proposal.rs +++ b/packages/dao-interface/src/proposal.rs @@ -1,4 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Addr; use cw2::ContractVersion; #[cw_serde] @@ -6,6 +7,12 @@ pub struct InfoResponse { pub info: ContractVersion, } +#[cw_serde] +pub struct GenericProposalInfo { + pub proposer: Addr, + pub start_height: u64, +} + #[cw_serde] #[derive(QueryResponses)] pub enum Query { @@ -19,6 +26,9 @@ pub enum Query { /// next proposal created. #[returns(::std::primitive::u64)] NextProposalId {}, + /// Returns generic proposal information + #[returns(GenericProposalInfo)] + GenericProposalInfo { proposal_id: ::std::primitive::u64 }, } mod tests { @@ -34,6 +44,7 @@ mod tests { Query::Dao {} => (), Query::Info {} => (), Query::NextProposalId {} => (), + Query::GenericProposalInfo { proposal_id: _ } => (), } } } diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index 9b191be86..e8eebb9b9 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -62,3 +62,4 @@ dao-voting-onft-staked = { workspace = true } dao-voting-token-staked = { workspace = true } voting-v1 = { workspace = true } stake-cw20-v03 = { workspace = true } +dao-proposal-incentives = { workspace = true } \ No newline at end of file diff --git a/packages/dao-testing/src/contracts.rs b/packages/dao-testing/src/contracts.rs index 1739ed124..51ee57df5 100644 --- a/packages/dao-testing/src/contracts.rs +++ b/packages/dao-testing/src/contracts.rs @@ -216,3 +216,13 @@ pub fn dao_test_custom_factory() -> Box> { .with_reply(dao_test_custom_factory::contract::reply); Box::new(contract) } + +pub fn dao_proposal_incentives_contract() -> Box> { + let contract = ContractWrapper::new( + dao_proposal_incentives::contract::execute, + dao_proposal_incentives::contract::instantiate, + dao_proposal_incentives::contract::query, + ); + + Box::new(contract) +} From dbab201e261134ef3c89ab2b37da1d4f3219674f Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 15:08:40 -0600 Subject: [PATCH 30/47] Fix clippy errors --- .../dao-proposal-incentives/src/execute.rs | 54 +++++++++---------- .../dao-voting-incentives/src/contract.rs | 16 +++--- .../external/dao-voting-incentives/src/lib.rs | 3 -- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs index b7d30dfe4..bafeac650 100644 --- a/contracts/external/dao-proposal-incentives/src/execute.rs +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -29,36 +29,34 @@ pub fn proposal_hook( )?; // Check prop status and type of hook - match msg { - ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } => { - // If prop status is success, add message to pay out rewards - // Otherwise, do nothing - if new_status == Status::Passed.to_string() { - // Query for the proposal - let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( - info.sender, - &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, - )?; - - // Load proposal incentives config - let proposal_incentives = PROPOSAL_INCENTIVES - .may_load_at_height(deps.storage, proposal_info.start_height)?; - - // Append the message if found - if let Some(proposal_incentives) = proposal_incentives { - msgs.push(proposal_incentives.denom.get_transfer_to_message( - &proposal_info.proposer, - proposal_incentives.rewards_per_proposal, - )?); - attrs = proposal_incentives.into_attributes(); - attrs.push(Attribute { - key: "proposer".to_string(), - value: proposal_info.proposer.to_string(), - }); - } + + if let ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } = msg { + // If prop status is success, add message to pay out rewards + // Otherwise, do nothing + if new_status == Status::Passed.to_string() { + // Query for the proposal + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender, + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id: id }, + )?; + + // Load proposal incentives config + let proposal_incentives = PROPOSAL_INCENTIVES + .may_load_at_height(deps.storage, proposal_info.start_height)?; + + // Append the message if found + if let Some(proposal_incentives) = proposal_incentives { + msgs.push(proposal_incentives.denom.get_transfer_to_message( + &proposal_info.proposer, + proposal_incentives.rewards_per_proposal, + )?); + attrs = proposal_incentives.into_attributes(); + attrs.push(Attribute { + key: "proposer".to_string(), + value: proposal_info.proposer.to_string(), + }); } } - _ => {} } } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 8ee17afc0..f68cbde11 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -57,8 +57,8 @@ pub fn execute( // TODO how to claim for many epochs efficiently? pub fn execute_claim( deps: DepsMut, - env: Env, - info: MessageInfo, + _env: Env, + _info: MessageInfo, ) -> Result { // Check epoch should advance @@ -69,7 +69,7 @@ pub fn execute_claim( // Load prop count for epoch // Load voting incentives config - let voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; + let _voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; // Need total vote count for epoch // Rewards = (user vote count / prop count) / total_vote_count * voting incentives @@ -82,10 +82,10 @@ pub fn execute_claim( // TODO support cw20 tokens // TODO make sure config can't lock DAO pub fn execute_vote_hook( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: VoteHookMsg, + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: VoteHookMsg, ) -> Result { // Check epoch should advance @@ -102,7 +102,7 @@ pub fn execute_vote_hook( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address } => unimplemented!(), + QueryMsg::Rewards { address: _ } => unimplemented!(), QueryMsg::Config {} => unimplemented!(), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index d1800adbc..595daabe0 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -5,7 +5,4 @@ mod error; pub mod msg; pub mod state; -#[cfg(test)] -mod tests; - pub use crate::error::ContractError; From 3597697f1da66052bd6dba7bd21f543ef2c78330 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 31 Jan 2024 15:18:49 -0600 Subject: [PATCH 31/47] More clippy --- .../dao-proposal-incentives/src/tests.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 340952ab1..2d58c275c 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -142,7 +142,7 @@ fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> AnyResult Date: Wed, 31 Jan 2024 21:25:39 -0600 Subject: [PATCH 32/47] Schema + clippy fix --- .../schema/cw-admin-factory.json | 69 -- .../schema/dao-proposal-incentives.json | 623 ++++++++++++++++++ .../dao-proposal-incentives/src/tests.rs | 2 +- .../external/dao-voting-incentives/README.md | 4 +- .../dao-voting-incentives/src/tests.rs | 1 - 5 files changed, 626 insertions(+), 73 deletions(-) delete mode 100644 contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json delete mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json b/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json deleted file mode 100644 index f1a1e1254..000000000 --- a/contracts/external/dao-proposal-incentives/schema/cw-admin-factory.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "contract_name": "cw-admin-factory", - "contract_version": "2.4.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", - "type": "object", - "required": [ - "instantiate_contract_with_self_admin" - ], - "properties": { - "instantiate_contract_with_self_admin": { - "type": "object", - "required": [ - "code_id", - "instantiate_msg", - "label" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - }, - "label": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "type": "string", - "enum": [] - }, - "migrate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MigrateMsg", - "type": "object", - "additionalProperties": false - }, - "sudo": null, - "responses": {} -} diff --git a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json new file mode 100644 index 000000000..2d02b5883 --- /dev/null +++ b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json @@ -0,0 +1,623 @@ +{ + "contract_name": "dao-proposal-incentives", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "owner", + "proposal_incentives" + ], + "properties": { + "owner": { + "description": "The contract's owner using cw-ownable", + "type": "string" + }, + "proposal_incentives": { + "description": "Rewards to pay out for successful proposals.", + "allOf": [ + { + "$ref": "#/definitions/ProposalIncentivesUnchecked" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "ProposalIncentivesUnchecked": { + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/UncheckedDenom" + }, + "rewards_per_proposal": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Fires when a new proposal status has changed.", + "type": "object", + "required": [ + "proposal_hook" + ], + "properties": { + "proposal_hook": { + "$ref": "#/definitions/ProposalHookMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_proposal_incentives" + ], + "properties": { + "update_proposal_incentives": { + "type": "object", + "required": [ + "proposal_incentives" + ], + "properties": { + "proposal_incentives": { + "$ref": "#/definitions/ProposalIncentivesUnchecked" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ProposalHookMsg": { + "description": "An enum representing proposal hook messages. Either a new proposal hook, fired when a new proposal is created, or a proposal status hook, fired when a proposal changes status.", + "oneOf": [ + { + "type": "object", + "required": [ + "new_proposal" + ], + "properties": { + "new_proposal": { + "type": "object", + "required": [ + "id", + "proposer" + ], + "properties": { + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "proposer": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "proposal_status_changed" + ], + "properties": { + "proposal_status_changed": { + "type": "object", + "required": [ + "id", + "new_status", + "old_status" + ], + "properties": { + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "new_status": { + "type": "string" + }, + "old_status": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "ProposalIncentivesUnchecked": { + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/UncheckedDenom" + }, + "rewards_per_proposal": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the proposal incentives", + "type": "object", + "required": [ + "proposal_incentives" + ], + "properties": { + "proposal_incentives": { + "type": "object", + "properties": { + "height": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the contract's ownership information", + "type": "object", + "required": [ + "ownership" + ], + "properties": { + "ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_compatible" + ], + "properties": { + "from_compatible": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "sudo": null, + "responses": { + "ownership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Ownership_for_String", + "description": "The contract's ownership info", + "type": "object", + "properties": { + "owner": { + "description": "The contract's current owner. `None` if the ownership has been renounced.", + "type": [ + "string", + "null" + ] + }, + "pending_expiry": { + "description": "The deadline for the pending owner to accept the ownership. `None` if there isn't a pending ownership transfer, or if a transfer exists and it doesn't have a deadline.", + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "pending_owner": { + "description": "The account who has been proposed to take over the ownership. `None` if there isn't a pending ownership transfer.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "proposal_incentives": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalIncentives", + "description": "Incentives for passing successful proposals", + "type": "object", + "required": [ + "denom", + "rewards_per_proposal" + ], + "properties": { + "denom": { + "$ref": "#/definitions/CheckedDenom" + }, + "rewards_per_proposal": { + "description": "The rewards to pay out per successful proposal.", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 2d58c275c..6afc2dedf 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -331,7 +331,7 @@ pub fn test_hook() { .send_tokens( Addr::unchecked(ADMIN), dao_proposal_incentives_addr.clone(), - &vec![Coin { + &[Coin { denom: DENOM.to_string(), amount: Uint128::new(1000), }], diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index f41943baf..df486cb0c 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -9,9 +9,9 @@ When creating this contract, the DAO specifies an `epoch_duration` and an amount At the end of the epoch, rewards are payable as follows: -``` +`` rewards = (user vote count / prop count) / total_vote_count * voting incentives -``` +`` If no proposals happen during an epoch, no rewards are paid out. diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs deleted file mode 100644 index 8b1378917..000000000 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ /dev/null @@ -1 +0,0 @@ - From 2bf1ec18585e175b80d5e0a72da334bc67f3e8a9 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 12:32:39 -0600 Subject: [PATCH 33/47] Progress on voting incentives Need to add tests --- Cargo.lock | 3 + .../dao-proposal-incentives/src/error.rs | 3 + .../dao-proposal-incentives/src/execute.rs | 14 +- .../external/dao-voting-incentives/Cargo.toml | 5 +- .../schema/cw-admin-factory.json | 69 -- .../schema/dao-voting-incentives.json | 695 ++++++++++++++++++ .../dao-voting-incentives/src/contract.rs | 113 ++- .../dao-voting-incentives/src/error.rs | 33 +- .../dao-voting-incentives/src/execute.rs | 226 ++++++ .../external/dao-voting-incentives/src/lib.rs | 2 + .../external/dao-voting-incentives/src/msg.rs | 48 +- .../dao-voting-incentives/src/query.rs | 23 + .../dao-voting-incentives/src/state.rs | 95 ++- 13 files changed, 1143 insertions(+), 186 deletions(-) delete mode 100644 contracts/external/dao-voting-incentives/schema/cw-admin-factory.json create mode 100644 contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json create mode 100644 contracts/external/dao-voting-incentives/src/execute.rs create mode 100644 contracts/external/dao-voting-incentives/src/query.rs diff --git a/Cargo.lock b/Cargo.lock index 6e836dcdb..53bd7dc2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2495,11 +2495,14 @@ version = "2.5.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "cw-denom 2.5.0", "cw-hooks 2.5.0", "cw-multi-test", + "cw-ownable", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "cw2 1.1.2", + "cw20 1.1.2", "cw20-base 1.1.2", "dao-dao-core 2.5.0", "dao-hooks 2.5.0", diff --git a/contracts/external/dao-proposal-incentives/src/error.rs b/contracts/external/dao-proposal-incentives/src/error.rs index ee3ba8822..57a1a362c 100644 --- a/contracts/external/dao-proposal-incentives/src/error.rs +++ b/contracts/external/dao-proposal-incentives/src/error.rs @@ -29,4 +29,7 @@ pub enum ContractError { #[error("No reward per proposal given")] NoRewardPerProposal {}, + + #[error("Proposal module is inactive")] + ProposalModuleIsInactive {}, } diff --git a/contracts/external/dao-proposal-incentives/src/execute.rs b/contracts/external/dao-proposal-incentives/src/execute.rs index bafeac650..95267ff27 100644 --- a/contracts/external/dao-proposal-incentives/src/execute.rs +++ b/contracts/external/dao-proposal-incentives/src/execute.rs @@ -2,7 +2,10 @@ use cosmwasm_std::{Attribute, CosmosMsg, DepsMut, Env, MessageInfo, Response}; use cw20::Cw20ReceiveMsg; use cw_ownable::{assert_owner, get_ownership}; use dao_hooks::proposal::ProposalHookMsg; -use dao_interface::{proposal::GenericProposalInfo, state::ProposalModule}; +use dao_interface::{ + proposal::GenericProposalInfo, + state::{ProposalModule, ProposalModuleStatus}, +}; use dao_voting::status::Status; use crate::{msg::ProposalIncentivesUnchecked, state::PROPOSAL_INCENTIVES, ContractError}; @@ -21,15 +24,19 @@ pub fn proposal_hook( if let Some(owner) = ownership.owner { // Validate the message is coming from a proposal module of the owner (DAO) - deps.querier.query_wasm_smart::( + let proposal_module = deps.querier.query_wasm_smart::( owner, &dao_interface::msg::QueryMsg::ProposalModule { address: info.sender.to_string(), }, )?; - // Check prop status and type of hook + // If the proposal module is disabled, then return error + if proposal_module.status == ProposalModuleStatus::Disabled { + return Err(ContractError::ProposalModuleIsInactive {}); + } + // Check prop status and type of hook if let ProposalHookMsg::ProposalStatusChanged { id, new_status, .. } = msg { // If prop status is success, add message to pay out rewards // Otherwise, do nothing @@ -104,6 +111,7 @@ pub fn receive_cw20( info: MessageInfo, _cw20_receive_msg: Cw20ReceiveMsg, ) -> Result { + // We do not check cw20, because the expected fund can change over time Ok(Response::new() .add_attribute("action", "receive_cw20") .add_attribute("cw20", info.sender)) diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index a64900db1..fbeccc8c0 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-voting-incentives" -authors = ["Jake Hartnell "] +authors = ["Jake Hartnell ", "ismellike"] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } @@ -26,6 +26,9 @@ dao-interface = { workspace = true } dao-voting = { workspace = true } thiserror = { workspace = true } cw-utils = { workspace = true } +cw-denom = { workspace = true } +cw-ownable = { workspace = true } +cw20 = { workspace = true } [dev-dependencies] cosmwasm-schema = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json b/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json deleted file mode 100644 index f1a1e1254..000000000 --- a/contracts/external/dao-voting-incentives/schema/cw-admin-factory.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "contract_name": "cw-admin-factory", - "contract_version": "2.4.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Instantiates the target contract with the provided instantiate message and code id and updates the contract's admin to be itself.", - "type": "object", - "required": [ - "instantiate_contract_with_self_admin" - ], - "properties": { - "instantiate_contract_with_self_admin": { - "type": "object", - "required": [ - "code_id", - "instantiate_msg", - "label" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - }, - "label": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "type": "string", - "enum": [] - }, - "migrate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MigrateMsg", - "type": "object", - "additionalProperties": false - }, - "sudo": null, - "responses": {} -} diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json new file mode 100644 index 000000000..0bfbb8c10 --- /dev/null +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -0,0 +1,695 @@ +{ + "contract_name": "dao-voting-incentives", + "contract_version": "2.4.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "denom", + "expiration", + "owner" + ], + "properties": { + "denom": { + "description": "The denom to distribute", + "allOf": [ + { + "$ref": "#/definitions/UncheckedDenom" + } + ] + }, + "expiration": { + "description": "The expiration of the voting incentives", + "allOf": [ + { + "$ref": "#/definitions/Expiration" + } + ] + }, + "owner": { + "description": "The contract's owner using cw-ownable", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "UncheckedDenom": { + "description": "A denom that has not been checked to confirm it points to a valid asset.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Fires when a new vote is cast.", + "type": "object", + "required": [ + "vote_hook" + ], + "properties": { + "vote_hook": { + "$ref": "#/definitions/VoteHookMsg" + } + }, + "additionalProperties": false + }, + { + "description": "Claim rewards", + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Expire the voting incentives period", + "type": "object", + "required": [ + "expire" + ], + "properties": { + "expire": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteHookMsg": { + "description": "An enum representing vote hooks, fired when new votes are cast.", + "oneOf": [ + { + "type": "object", + "required": [ + "new_vote" + ], + "properties": { + "new_vote": { + "type": "object", + "required": [ + "proposal_id", + "vote", + "voter" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "type": "string" + }, + "voter": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the config", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the claimable rewards for the given address.", + "type": "object", + "required": [ + "rewards" + ], + "properties": { + "rewards": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the expected rewards for the given address", + "type": "object", + "required": [ + "expected_rewards" + ], + "properties": { + "expected_rewards": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Query the contract's ownership information", + "type": "object", + "required": [ + "ownership" + ], + "properties": { + "ownership": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "from_compatible" + ], + "properties": { + "from_compatible": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "sudo": null, + "responses": { + "config": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "Top level config type for core module.", + "type": "object", + "required": [ + "automatically_add_cw20s", + "automatically_add_cw721s", + "description", + "name" + ], + "properties": { + "automatically_add_cw20s": { + "description": "If true the contract will automatically add received cw20 tokens to its treasury.", + "type": "boolean" + }, + "automatically_add_cw721s": { + "description": "If true the contract will automatically add received cw721 tokens to its treasury.", + "type": "boolean" + }, + "dao_uri": { + "description": "The URI for the DAO as defined by the DAOstar standard ", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "A description of the contract.", + "type": "string" + }, + "image_url": { + "description": "An optional image URL for displaying alongside the contract.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "The name of the contract.", + "type": "string" + } + }, + "additionalProperties": false + }, + "expected_rewards": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardResponse", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "$ref": "#/definitions/CheckedDenom" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "ownership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Ownership_for_String", + "description": "The contract's ownership info", + "type": "object", + "properties": { + "owner": { + "description": "The contract's current owner. `None` if the ownership has been renounced.", + "type": [ + "string", + "null" + ] + }, + "pending_expiry": { + "description": "The deadline for the pending owner to accept the ownership. `None` if there isn't a pending ownership transfer, or if a transfer exists and it doesn't have a deadline.", + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "pending_owner": { + "description": "The account who has been proposed to take over the ownership. `None` if there isn't a pending ownership transfer.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false, + "definitions": { + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "rewards": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RewardResponse", + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "$ref": "#/definitions/CheckedDenom" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "CheckedDenom": { + "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", + "oneOf": [ + { + "description": "A native (bank module) asset.", + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "description": "A cw20 asset.", + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index f68cbde11..32ca6e86b 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -1,13 +1,15 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{ + to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, +}; use cw2::set_contract_version; -use cw_utils::must_pay; -use dao_hooks::vote::VoteHookMsg; +use cw_ownable::get_ownership; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{DAO, VOTING_INCENTIVES}; +use crate::state::{Config, CONFIG}; +use crate::{execute, query}; pub(crate) const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -15,30 +17,41 @@ pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // Save DAO, assumes the sender is the DAO - DAO.save(deps.storage, &deps.api.addr_validate(&msg.dao)?)?; + // Save ownership + let ownership = cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; - // Save voting incentives config - VOTING_INCENTIVES.save(deps.storage, &msg.voting_incentives)?; + // Validate denom + let denom = msg.denom.into_checked(deps.as_ref())?; + + // Validate expiration + if msg.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } - // Check initial deposit is enough to pay out rewards for at least one epoch - let amount = must_pay(&info, &msg.voting_incentives.rewards_per_epoch.denom)?; - if amount < msg.voting_incentives.rewards_per_epoch.amount { - return Err(ContractError::InsufficientInitialDeposit { - expected: msg.voting_incentives.rewards_per_epoch.amount, - actual: amount, - }); - }; + // Save voting incentives config + CONFIG.save( + deps.storage, + &Config { + start_height: env.block.height, + expiration: msg.expiration, + denom: denom.clone(), + total_votes: Uint128::zero(), + expiration_balance: None, + }, + )?; Ok(Response::new() .add_attribute("method", "instantiate") - .add_attribute("creator", info.sender)) + .add_attribute("creator", info.sender) + .add_attribute("expiration", msg.expiration.to_string()) + .add_attribute("denom", denom.to_string()) + .add_attributes(ownership.into_attributes())) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -49,61 +62,25 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Claim {} => execute_claim(deps, env, info), - ExecuteMsg::VoteHook(msg) => execute_vote_hook(deps, env, info, msg), + ExecuteMsg::Claim {} => execute::claim(deps, env, info), + ExecuteMsg::VoteHook(msg) => execute::vote_hook(deps, env, info, msg), + ExecuteMsg::Expire {} => execute::expire(deps, env, info), + ExecuteMsg::UpdateOwnership(action) => execute::update_ownership(deps, env, info, action), + ExecuteMsg::Receive(cw20_receive_msg) => { + execute::receive_cw20(deps, env, info, cw20_receive_msg) + } } } -// TODO how to claim for many epochs efficiently? -pub fn execute_claim( - deps: DepsMut, - _env: Env, - _info: MessageInfo, -) -> Result { - // Check epoch should advance - - // Save last claimed epoch - - // Load user vote count for epoch? - - // Load prop count for epoch - - // Load voting incentives config - let _voting_incentives = VOTING_INCENTIVES.load(deps.storage)?; - - // Need total vote count for epoch - // Rewards = (user vote count / prop count) / total_vote_count * voting incentives - - // Pay out rewards - - Ok(Response::default().add_attribute("action", "claim")) -} - -// TODO support cw20 tokens -// TODO make sure config can't lock DAO -pub fn execute_vote_hook( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: VoteHookMsg, -) -> Result { - // Check epoch should advance - - // TODO need some state to handle this - // Check that the vote is not a changed vote (i.e. the user has already voted - // on the prop). - - // Save (user, epoch), vote count - // Update (epoch, prop count) - - Ok(Response::default().add_attribute("action", "vote_hook")) -} - #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address: _ } => unimplemented!(), - QueryMsg::Config {} => unimplemented!(), + QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, address)?), + QueryMsg::ExpectedRewards { address } => { + to_json_binary(&query::expected_rewards(deps, env, address)?) + } + QueryMsg::Config {} => to_json_binary(&query::config(deps)?), + QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), } } diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 2b1469dcb..15b5024ad 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -1,5 +1,7 @@ -use cosmwasm_std::{StdError, Uint128}; -use cw_utils::{ParseReplyError, PaymentError}; +use cosmwasm_std::{CheckedMultiplyFractionError, OverflowError, StdError}; +use cw_denom::{CheckedDenom, DenomError}; +use cw_ownable::OwnershipError; +use cw_utils::Expiration; use thiserror::Error; #[derive(Error, Debug)] @@ -8,17 +10,32 @@ pub enum ContractError { Std(#[from] StdError), #[error("{0}")] - ParseReplyError(#[from] ParseReplyError), + DenomError(#[from] DenomError), #[error("{0}")] - PaymentError(#[from] PaymentError), + OwnershipError(#[from] OwnershipError), - #[error("You need to deposit enough incentives for at least one epoch of incentives. Expected {expected}, got {actual}.")] - InsufficientInitialDeposit { expected: Uint128, actual: Uint128 }, + #[error("{0}")] + CheckedMultiplyFractionError(#[from] CheckedMultiplyFractionError), + + #[error("{0}")] + OverflowError(#[from] OverflowError), #[error("Unauthorized")] Unauthorized {}, - #[error("An unknown reply ID was received.")] - UnknownReplyID {}, + #[error("NotExpired")] + NotExpired { expiration: Expiration }, + + #[error("AlreadyExpired")] + AlreadyExpired {}, + + #[error("Proposal module is inactive")] + ProposalModuleIsInactive {}, + + #[error("UnexpectedFunds")] + UnexpectedFunds { + expected: CheckedDenom, + received: CheckedDenom, + }, } diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs new file mode 100644 index 000000000..df5a75205 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -0,0 +1,226 @@ +use cosmwasm_std::{Attribute, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; +use cw20::Cw20ReceiveMsg; +use cw_denom::CheckedDenom; +use cw_ownable::get_ownership; +use dao_hooks::vote::VoteHookMsg; +use dao_interface::{ + proposal::GenericProposalInfo, + state::{ProposalModule, ProposalModuleStatus}, +}; + +use crate::{ + state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_VOTE_COUNT}, + ContractError, +}; + +pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + // Get reward information + let reward = reward(deps.as_ref(), &info.sender)?; + + // If the user has rewards, then we should generate a message + let mut msgs = vec![]; + if !reward.amount.is_zero() { + msgs.push( + reward + .denom + .get_transfer_to_message(&info.sender, reward.amount)?, + ); + } + + // Clean state + USER_VOTE_COUNT.remove(deps.storage, &info.sender); + + Ok(Response::new() + .add_attribute("action", "claim") + .add_attribute("denom", reward.denom.to_string()) + .add_attribute("amount", reward.amount) + .add_messages(msgs)) +} + +pub fn update_ownership( + deps: DepsMut, + env: Env, + info: MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + + Ok(Response::new() + .add_attribute("action", "update_ownership") + .add_attributes(ownership.into_attributes())) +} + +pub fn vote_hook( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: VoteHookMsg, +) -> Result { + let mut attrs: Vec = vec![]; + + // Get ownership + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + // Validate the message is coming from a proposal module of the owner (DAO) + let proposal_module = deps.querier.query_wasm_smart::( + owner, + &dao_interface::msg::QueryMsg::ProposalModule { + address: info.sender.to_string(), + }, + )?; + + // If the proposal module is disabled, then return error + if proposal_module.status == ProposalModuleStatus::Disabled { + return Err(ContractError::ProposalModuleIsInactive {}); + } + + // Check type of hook + match msg { + VoteHookMsg::NewVote { + proposal_id, voter, .. + } => { + if let Ok(voter) = deps.api.addr_validate(&voter) { + // Get config + let mut config = CONFIG.load(deps.storage)?; + + // Check if the voting incentives have expired + if config.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } + + // Get the proposal info + // If we have a value in the cache, then return the value + // If we don't have a value, then query for the value and set it in the cache + let proposal_info = if GENERIC_PROPOSAL_INFO + .has(deps.storage, (&info.sender, proposal_id)) + { + GENERIC_PROPOSAL_INFO.load(deps.storage, (&info.sender, proposal_id))? + } else { + let proposal_info: GenericProposalInfo = deps.querier.query_wasm_smart( + info.sender.clone(), + &dao_interface::proposal::Query::GenericProposalInfo { proposal_id }, + )?; + + GENERIC_PROPOSAL_INFO.save( + deps.storage, + (&info.sender, proposal_id), + &proposal_info, + )?; + + proposal_info + }; + + // Check if the vote came from a proposal at or after the start of the voting incentives + if proposal_info.start_height >= config.start_height { + // Increment counts + let user_votes = USER_VOTE_COUNT.update( + deps.storage, + &voter, + |x| -> StdResult { + Ok(x.unwrap_or_default().checked_add(Uint128::one())?) + }, + )?; + config.total_votes = config.total_votes.checked_add(Uint128::one())?; + CONFIG.save(deps.storage, &config)?; + + // Set attributes + attrs = vec![ + Attribute { + key: "total_votes".to_string(), + value: config.total_votes.to_string(), + }, + Attribute { + key: "user_votes".to_string(), + value: user_votes.to_string(), + }, + Attribute { + key: "user".to_string(), + value: voter.to_string(), + }, + ]; + } + } + } + } + } + + Ok(Response::new() + .add_attribute("action", "vote_hook") + .add_attributes(attrs)) +} + +pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result { + // Get the config + let mut config = CONFIG.load(deps.storage)?; + + // If already expired, then return an error + if config.expiration_balance.is_some() { + return Err(ContractError::AlreadyExpired {}); + } + + // Ensure the voting incentives period has passed expiration + if !config.expiration.is_expired(&env.block) { + return Err(ContractError::NotExpired { + expiration: config.expiration, + }); + } + + // Get the available balance to distribute + let balance = config + .denom + .query_balance(&deps.querier, &env.contract.address)?; + + // Save the balance + config.expiration_balance = Some(balance); + CONFIG.save(deps.storage, &config)?; + + // If no votes have occurred, then funds should be sent to the owner + let mut msgs = vec![]; + if USER_VOTE_COUNT.is_empty(deps.storage) { + let ownership = get_ownership(deps.storage)?; + + if let Some(owner) = ownership.owner { + msgs.push(config.denom.get_transfer_to_message(&owner, balance)?); + } + } + + // Clean state + GENERIC_PROPOSAL_INFO.clear(deps.storage); + + Ok(Response::new() + .add_attribute("action", "expire") + .add_attribute("balance", balance) + .add_messages(msgs)) +} + +pub fn receive_cw20( + deps: DepsMut, + _env: Env, + info: MessageInfo, + _cw20_receive_msg: Cw20ReceiveMsg, +) -> Result { + let config = CONFIG.load(deps.storage)?; + + // Do not accept unexpected cw20 + match &config.denom { + CheckedDenom::Native(_) => { + return Err(ContractError::UnexpectedFunds { + expected: config.denom, + received: CheckedDenom::Cw20(info.sender), + }) + } + CheckedDenom::Cw20(expected_cw20) => { + if expected_cw20 != info.sender { + return Err(ContractError::UnexpectedFunds { + expected: config.denom, + received: CheckedDenom::Cw20(info.sender), + }); + } + } + } + + Ok(Response::new() + .add_attribute("action", "receive_cw20") + .add_attribute("cw20", info.sender)) +} diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index 595daabe0..d2f25785c 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -2,7 +2,9 @@ pub mod contract; mod error; +pub mod execute; pub mod msg; +pub mod query; pub mod state; pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 5298657e6..1937ab74b 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -1,42 +1,56 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Uint128; +use cw20::Cw20ReceiveMsg; +use cw_denom::{CheckedDenom, UncheckedDenom}; +use cw_ownable::cw_ownable_query; +use cw_utils::Expiration; use dao_hooks::vote::VoteHookMsg; - -use crate::state::VotingIncentives; +use dao_interface::state::Config; #[cw_serde] pub struct InstantiateMsg { - /// DAO address - pub dao: String, - /// Rewards to pay out for voting. - pub voting_incentives: VotingIncentives, + /// The contract's owner using cw-ownable + pub owner: String, + /// The denom to distribute + pub denom: UncheckedDenom, + /// The expiration of the voting incentives + pub expiration: Expiration, } #[cw_serde] pub enum ExecuteMsg { /// Fires when a new vote is cast. VoteHook(VoteHookMsg), - /// Claim rewards. + /// Claim rewards Claim {}, + /// Expire the voting incentives period + Expire {}, + UpdateOwnership(cw_ownable::Action), + Receive(Cw20ReceiveMsg), } +#[cw_ownable_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - /// Returns the config. - #[returns(ConfigResponse)] + /// Returns the config + #[returns(Config)] Config {}, - /// Returns the rewards for the given address. - #[returns(cosmwasm_std::Uint128)] + /// Returns the claimable rewards for the given address. + #[returns(RewardResponse)] Rewards { address: String }, + /// Returns the expected rewards for the given address + #[returns(RewardResponse)] + ExpectedRewards { address: String }, } #[cw_serde] -pub struct ConfigResponse { - /// DAO address - pub dao: String, - /// Rewards to pay out for voting. - pub voting_incentives: VotingIncentives, +pub enum MigrateMsg { + FromCompatible {}, } #[cw_serde] -pub struct MigrateMsg {} +pub struct RewardResponse { + pub denom: CheckedDenom, + pub amount: Uint128, +} diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs new file mode 100644 index 000000000..96a6877ea --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -0,0 +1,23 @@ +use cosmwasm_std::{Deps, Env, StdError, StdResult}; + +use crate::{ + msg::RewardResponse, + state::{self, Config, CONFIG}, +}; + +pub fn rewards(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + state::reward(deps, &address).map_err(|x| StdError::GenericErr { msg: x.to_string() }) +} + +pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + state::expected_reward(deps, env, &address) + .map_err(|x| StdError::GenericErr { msg: x.to_string() }) +} + +pub fn config(deps: Deps) -> StdResult { + CONFIG.load(deps.storage) +} diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 730cd7fe3..571482860 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -1,33 +1,88 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin, Timestamp}; +use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Env, Uint128}; +use cw_denom::CheckedDenom; use cw_storage_plus::{Item, Map}; +use cw_utils::Expiration; +use dao_interface::proposal::GenericProposalInfo; -/// The address of the DAO this contract serves -pub const DAO: Item = Item::new("dao"); +use crate::{msg::RewardResponse, ContractError}; /// Incentives for voting #[cw_serde] -pub struct VotingIncentives { - /// Epoch duration in seconds. Used for reward calculation. - pub epoch_duration: Timestamp, - /// The rewards to pay out per epoch. - pub rewards_per_epoch: Coin, +pub struct Config { + /// The start height of the voting incentives + pub start_height: u64, + /// The expiration of these voting incentives + pub expiration: Expiration, + /// The total rewards to be distributed + pub denom: CheckedDenom, + /// The total number of votes + pub total_votes: Uint128, + /// The balance at expiration + pub expiration_balance: Option, } -/// Holds VotingIncentives state -pub const VOTING_INCENTIVES: Item = Item::new("voting_incentives"); +/// A map of user address to vote count +pub const USER_VOTE_COUNT: Map<&Addr, Uint128> = Map::new("user_vote_count"); +/// The voting incentives config +pub const CONFIG: Item = Item::new("config"); +/// A cache of generic proposal information (proposal_module, proposal_id) +pub const GENERIC_PROPOSAL_INFO: Map<(&Addr, u64), GenericProposalInfo> = + Map::new("generic_proposal_info"); -/// The current epoch -pub const EPOCH: Item = Item::new("epoch"); +/// A method to load reward information +pub fn reward(deps: Deps, addr: &Addr) -> Result { + let config = CONFIG.load(deps.storage)?; -/// A map of addresses to their last claimed epoch -pub const LAST_CLAIMED_EPOCHS: Map = Map::new("last_claimed_epoch"); + match config.expiration_balance { + Some(balance) => { + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); -/// A map of epochs to prop count -pub const EPOCH_PROPOSAL_COUNT: Map = Map::new("epoch_proposal_count"); + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) + } + None => Err(ContractError::NotExpired { + expiration: config.expiration, + }), + } +} + +/// A method to load the expected reward information +/// The expected reward method can differ from the actual reward, because the balance is saved in state after expiration +pub fn expected_reward(deps: Deps, env: Env, addr: &Addr) -> Result { + let config = CONFIG.load(deps.storage)?; -/// A map of epochs to total vote count -pub const EPOCH_TOTAL_VOTE_COUNT: Map = Map::new("epoch_total_vote_count"); + // Get the voting incentives balance + let balance = config + .denom + .query_balance(&deps.querier, &env.contract.address)?; -/// A map of user addresses + epoch to vote count -pub const USER_EPOCH_VOTE_COUNT: Map<(Addr, u64), u64> = Map::new("user_epoch_vote_count"); + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); + + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) +} + +fn calculate_reward( + total_votes: Uint128, + user_votes: Uint128, + balance: Uint128, +) -> Result { + if balance.is_zero() || user_votes.is_zero() || total_votes.is_zero() { + return Ok(Uint128::zero()); + } + + balance.checked_div_floor((user_votes, total_votes)) +} From 5c9383f75dbec7112320cd74852c756d3f37ab8c Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 15:55:33 -0600 Subject: [PATCH 34/47] Handle revoting and update readme's --- .../dao-proposal-incentives/README.md | 29 ++++++++- .../external/dao-voting-incentives/README.md | 42 +++++++----- .../dao-voting-incentives/src/execute.rs | 65 +++++++++++-------- .../dao-voting-incentives/src/state.rs | 3 + 4 files changed, 92 insertions(+), 47 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 106344544..f63d7b00a 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -3,8 +3,31 @@ [![dao-proposal-incentives on crates.io](https://img.shields.io/crates/v/dao-proposal-incentives.svg?logo=rust)](https://crates.io/crates/dao-proposal-incentives) [![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) -Allows for DAOs to offer incentives for making successful proposals. +This contract enables DAO's to incentivize members for making successful proposals. By integrating this contract, DAO's can automatically reward members whose proposals are successfully passed, using either native tokens or CW20 tokens. -To setup this contract, the DAO needs to add this contract as a `ProposalHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module, and the DAO must be the `owner` of this contract. When someone successfully passes a proposal the specified rewards are automatically paid out. +## Instantiate -The incentives can be configured as native or cw20 tokens, and the award is determined by the configuration at the passed proposal's `start_time`. \ No newline at end of file +To instantiate the contract, provide the following parameters: + +- `owner`: The DAO sending this contract proposal hooks. +- `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure. + +## Setup + +- This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules. +- The DAO must be set as the `owner` of this contract to manage incentives and ownership. + +## Execute + +- **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals. +- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. +- **UpdateProposalIncentives { proposal_incentives: ProposalIncentivesUnchecked }**: Updates the incentives configuration. This allows the DAO to modify the rewards for successful proposals. +- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. + +## Query + +- **ProposalIncentives { height: Option }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time. + +## Configuration + +The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. \ No newline at end of file diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index df486cb0c..dbb0da0e9 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,24 +1,32 @@ -# dao-voting-incentives +This contract enables DAOs to offer incentives for voting on DAO proposals. By rewarding active voters, DAOs can encourage greater community involvement and decision-making. -[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) -[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) +## Instantiate -Allows for DAOs to offer incentives for voting on DAO proposals. +To instantiate the contract, provide the following parameters: -When creating this contract, the DAO specifies an `epoch_duration` and an amount to pay out per epoch. Then, the DAO needs to add this contract as a `VoteHook` to the `dao-voting-single` or `dao-voting-multiple` proposal module. When DAO members vote, this contract keeps track of the proposals and who voted. +- `owner`: The DAO sending this contract voting hooks. +- `denom`: The denomination of the tokens to distribute as rewards. +- `expiration`: The expiration of the voting incentives period, defining how long the incentives are active. -At the end of the epoch, rewards are payable as follows: +## Configuration -`` -rewards = (user vote count / prop count) / total_vote_count * voting incentives -`` +- This contract should be added as a `VoteHook` to either the `dao-proposal-single` or `dao-proposal-multiple` proposal modules. +- The DAO must be set as the `owner` of this contract to manage incentives and ownership. -If no proposals happen during an epoch, no rewards are paid out. +If no votes are cast during the voting incentives period, then the contract's funds are sent to the `owner` on expiration. -## TODO -- [ ] Unit and Integration tests with a full DAO -- [ ] Make sure it works with multiple proposal modules (i.e. multiple choice and single choice) -- [ ] Make sure claiming rewards is gas effecient even if many epochs have passed. -- [ ] Support Cw20. -- [ ] Use `cw-ownable` to configure a contract owner who can update the voting incentives config. -- [ ] Add more info to the readme and delete this TODO section. +Rewards for a user are determined as such: `reward(user) = votes(user) * contract's balance / total votes` + +## Execute + +- **VoteHook(VoteHookMsg)**: Triggered when a new vote is cast. This is used to track voting activity and allocate rewards accordingly. +- **Claim {}**: Allows voters to claim their rewards after expiration. +- **Expire {}**: Expires the voting incentives period, allowing voters to claim rewards. +- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. +- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. + +## Query + +- **Config {}**: Returns the configuration of the voting incentives. +- **Rewards { address: String }**: Queries the claimable rewards for a specific address. +- **ExpectedRewards { address: String }**: Estimates the expected rewards for a specific address, based on current votes. diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index df5a75205..bed6fe22f 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -9,7 +9,7 @@ use dao_interface::{ }; use crate::{ - state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_VOTE_COUNT}, + state::{reward, CONFIG, GENERIC_PROPOSAL_INFO, USER_PROPOSAL_HAS_VOTED, USER_VOTE_COUNT}, ContractError, }; @@ -113,32 +113,42 @@ pub fn vote_hook( // Check if the vote came from a proposal at or after the start of the voting incentives if proposal_info.start_height >= config.start_height { - // Increment counts - let user_votes = USER_VOTE_COUNT.update( - deps.storage, - &voter, - |x| -> StdResult { - Ok(x.unwrap_or_default().checked_add(Uint128::one())?) - }, - )?; - config.total_votes = config.total_votes.checked_add(Uint128::one())?; - CONFIG.save(deps.storage, &config)?; - - // Set attributes - attrs = vec![ - Attribute { - key: "total_votes".to_string(), - value: config.total_votes.to_string(), - }, - Attribute { - key: "user_votes".to_string(), - value: user_votes.to_string(), - }, - Attribute { - key: "user".to_string(), - value: voter.to_string(), - }, - ]; + // Check if the user has already voted for the proposal + if !USER_PROPOSAL_HAS_VOTED.has(deps.storage, (&voter, proposal_id)) { + // Increment counts + let user_votes = USER_VOTE_COUNT.update( + deps.storage, + &voter, + |x| -> StdResult { + Ok(x.unwrap_or_default().checked_add(Uint128::one())?) + }, + )?; + config.total_votes = config.total_votes.checked_add(Uint128::one())?; + CONFIG.save(deps.storage, &config)?; + + // Set has voted + USER_PROPOSAL_HAS_VOTED.save( + deps.storage, + (&voter, proposal_id), + &true, + )?; + + // Set attributes + attrs = vec![ + Attribute { + key: "total_votes".to_string(), + value: config.total_votes.to_string(), + }, + Attribute { + key: "user_votes".to_string(), + value: user_votes.to_string(), + }, + Attribute { + key: "user".to_string(), + value: voter.to_string(), + }, + ]; + } } } } @@ -187,6 +197,7 @@ pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result = Map::new("user_vote_count"); +/// A map of user address with proposal id to has voted value +/// This map is useful for cases where a proposal module allows revoting, so users cannot spam votes for more rewards +pub const USER_PROPOSAL_HAS_VOTED: Map<(&Addr, u64), bool> = Map::new("user_proposal_has_voted"); /// The voting incentives config pub const CONFIG: Item = Item::new("config"); /// A cache of generic proposal information (proposal_module, proposal_id) From 22a13d1a07ba79aa44491e2ee59095db87461747 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Wed, 7 Feb 2024 15:59:11 -0600 Subject: [PATCH 35/47] Update README.md --- contracts/external/dao-voting-incentives/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index dbb0da0e9..645fcb2b2 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,3 +1,8 @@ +# dao-voting-incentives + +[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) +[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) + This contract enables DAOs to offer incentives for voting on DAO proposals. By rewarding active voters, DAOs can encourage greater community involvement and decision-making. ## Instantiate From 65fa0de382fb3fd95677424570ea9cac656384e1 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Thu, 8 Feb 2024 12:54:22 -0600 Subject: [PATCH 36/47] Work on voting tests I think there's a bug in the removal of multiple hooks at the same time --- Cargo.lock | 3 + Cargo.toml | 1 + .../dao-proposal-incentives/README.md | 8 +- .../dao-proposal-incentives/src/tests.rs | 59 +-- .../external/dao-voting-incentives/Cargo.toml | 3 + .../dao-voting-incentives/src/contract.rs | 7 + .../external/dao-voting-incentives/src/lib.rs | 3 + .../external/dao-voting-incentives/src/msg.rs | 3 + .../dao-voting-incentives/src/query.rs | 12 +- .../dao-voting-incentives/src/tests.rs | 470 ++++++++++++++++++ packages/dao-testing/Cargo.toml | 3 +- packages/dao-testing/src/contracts.rs | 14 +- 12 files changed, 541 insertions(+), 45 deletions(-) create mode 100644 contracts/external/dao-voting-incentives/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 53bd7dc2c..dbc58e3b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2310,6 +2310,7 @@ dependencies = [ "dao-voting-cw4 2.5.0", "dao-voting-cw721-roles", "dao-voting-cw721-staked", + "dao-voting-incentives", "dao-voting-onft-staked", "dao-voting-token-staked", "osmosis-std", @@ -2507,6 +2508,8 @@ dependencies = [ "dao-dao-core 2.5.0", "dao-hooks 2.5.0", "dao-interface 2.5.0", + "dao-proposal-single 2.5.0", + "dao-testing", "dao-voting 2.5.0", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index d9d399d9d..3e302b79f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,6 +124,7 @@ dao-voting-cw20-staked = { path = "./contracts/voting/dao-voting-cw20-staked", v dao-voting-cw4 = { path = "./contracts/voting/dao-voting-cw4", version = "2.5.0" } dao-voting-cw721-roles = { path = "./contracts/voting/dao-voting-cw721-roles", version = "2.5.0" } dao-voting-cw721-staked = { path = "./contracts/voting/dao-voting-cw721-staked", version = "2.5.0" } +dao-voting-incentives = { path = "./contracts/external/dao-voting-incentives", version = "2.5.0" } dao-voting-onft-staked = { path = "./contracts/voting/dao-voting-onft-staked", version = "2.5.0" } dao-voting-token-staked = { path = "./contracts/voting/dao-voting-token-staked", version = "2.5.0" } diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index f63d7b00a..45bd9e0db 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -12,11 +12,13 @@ To instantiate the contract, provide the following parameters: - `owner`: The DAO sending this contract proposal hooks. - `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure. -## Setup +## Configuration - This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules. - The DAO must be set as the `owner` of this contract to manage incentives and ownership. +The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. + ## Execute - **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals. @@ -27,7 +29,3 @@ To instantiate the contract, provide the following parameters: ## Query - **ProposalIncentives { height: Option }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time. - -## Configuration - -The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. \ No newline at end of file diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 6afc2dedf..2adca6808 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -2,17 +2,15 @@ use std::vec; use cosmwasm_std::{ testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Uint128, WasmMsg, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, }; use cw20::Cw20Coin; use cw_denom::{CheckedDenom, UncheckedDenom}; -use cw_multi_test::{ - error::AnyResult, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, -}; +use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; use cw_ownable::Ownership; use dao_testing::{ - contracts::{dao_proposal_incentives_contract, proposal_single_contract}, + contracts::{cw20_base_contract, dao_proposal_incentives_contract, proposal_single_contract}, helpers::instantiate_with_cw4_groups_governance, }; use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; @@ -35,15 +33,6 @@ struct Context { dao_proposal_incentives_code_id: u64, } -fn cw20_base_contract() -> Box> { - let contract = ContractWrapper::new( - cw20_base::contract::execute, - cw20_base::contract::instantiate, - cw20_base::contract::query, - ); - Box::new(contract) -} - fn get_context() -> Context { // Set up app with native balances let mut app = AppBuilder::default().build(|router, _, storage| { @@ -352,28 +341,26 @@ pub fn test_hook() { assert!(result.is_ok()); // Propose adding a hook - context - .app - .execute_contract( - Addr::unchecked(ADDR1), - context.proposal_single_addr.clone(), - &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { - title: "Add proposal hook".to_string(), - description: "Adding a proposal hook to test the dao_proposal_incentives contract" - .to_string(), - msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: context.proposal_single_addr.to_string(), - msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { - address: dao_proposal_incentives_addr.to_string(), - }) - .unwrap(), - funds: vec![], - })], - proposer: None, - }), - &[], - ) - .unwrap(); + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add proposal hook".to_string(), + description: "Adding a proposal hook to test the dao_proposal_incentives contract" + .to_string(), + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook { + address: dao_proposal_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + })], + proposer: None, + }), + &[], + ); + assert!(result.is_ok()); // Vote and execute the proposal to add the proposal hook vote_yes_on_proposal(&mut context, 1u64).unwrap(); diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index fbeccc8c0..be6d63c19 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -36,3 +36,6 @@ cw-multi-test = { workspace = true } dao-dao-core = { workspace = true, features = ["library"] } cw20-base = { workspace = true, features = ["library"] } cw-hooks = { workspace = true } +dao-testing = { workspace = true } +dao-hooks = { workspace = true } +dao-proposal-single = { workspace = true, features = ["library"] } \ No newline at end of file diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 32ca6e86b..75d5b6050 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -5,6 +5,7 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; use cw_ownable::get_ownership; +use cw_utils::Expiration; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; @@ -33,6 +34,11 @@ pub fn instantiate( if msg.expiration.is_expired(&env.block) { return Err(ContractError::AlreadyExpired {}); } + if let Expiration::Never {} = msg.expiration { + return Err(ContractError::NotExpired { + expiration: Expiration::Never {}, + }); + } // Save voting incentives config CONFIG.save( @@ -81,6 +87,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } QueryMsg::Config {} => to_json_binary(&query::config(deps)?), QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), + QueryMsg::Votes { address } => to_json_binary(&query::votes(deps, address)?), } } diff --git a/contracts/external/dao-voting-incentives/src/lib.rs b/contracts/external/dao-voting-incentives/src/lib.rs index d2f25785c..bed930ba1 100644 --- a/contracts/external/dao-voting-incentives/src/lib.rs +++ b/contracts/external/dao-voting-incentives/src/lib.rs @@ -7,4 +7,7 @@ pub mod msg; pub mod query; pub mod state; +#[cfg(test)] +mod tests; + pub use crate::error::ContractError; diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 1937ab74b..4eb0b7af4 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -42,6 +42,9 @@ pub enum QueryMsg { /// Returns the expected rewards for the given address #[returns(RewardResponse)] ExpectedRewards { address: String }, + /// Returns the votes count for the given address + #[returns(Uint128)] + Votes { address: String }, } #[cw_serde] diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs index 96a6877ea..dcee2772f 100644 --- a/contracts/external/dao-voting-incentives/src/query.rs +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -1,8 +1,8 @@ -use cosmwasm_std::{Deps, Env, StdError, StdResult}; +use cosmwasm_std::{Deps, Env, StdError, StdResult, Uint128}; use crate::{ msg::RewardResponse, - state::{self, Config, CONFIG}, + state::{self, Config, CONFIG, USER_VOTE_COUNT}, }; pub fn rewards(deps: Deps, address: String) -> StdResult { @@ -21,3 +21,11 @@ pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult StdResult { CONFIG.load(deps.storage) } + +pub fn votes(deps: Deps, address: String) -> StdResult { + let address = deps.api.addr_validate(&address)?; + + Ok(USER_VOTE_COUNT + .may_load(deps.storage, &address)? + .unwrap_or_default()) +} diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs new file mode 100644 index 000000000..de63a8419 --- /dev/null +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -0,0 +1,470 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env}, + to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, +}; + +use cw20::{Cw20Coin, Cw20ReceiveMsg}; +use cw_denom::UncheckedDenom; +use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; +use cw_utils::Expiration; +use dao_testing::{ + contracts::{cw20_base_contract, dao_voting_incentives_contract, proposal_single_contract}, + helpers::instantiate_with_cw4_groups_governance, +}; +use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold}; + +use crate::{ + contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + state::Config, +}; + +const ADMIN: &str = "admin"; +const ADDR1: &str = "addr1"; +const ADDR2: &str = "addr2"; +const DENOM: &str = "juno"; + +struct Context { + app: App, + cw20_addr: Addr, + proposal_single_addr: Addr, + dao_addr: Addr, + dao_voting_incentives_code_id: u64, +} + +fn get_context() -> Context { + // Set up app with native balances + let mut app = AppBuilder::default().build(|router, _, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked(ADMIN), + vec![Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + }); + + // Set up cw20 with balances + let cw20_code_id = app.store_code(cw20_base_contract()); + let cw20_addr = app + .instantiate_contract( + cw20_code_id, + Addr::unchecked(ADMIN), + &cw20_base::msg::InstantiateMsg { + name: "cw20 token".to_string(), + symbol: "cwtoken".to_string(), + decimals: 6, + initial_balances: vec![Cw20Coin { + address: ADMIN.to_string(), + amount: Uint128::new(1000), + }], + mint: None, + marketing: None, + }, + &[], + "cw20-base", + None, + ) + .unwrap(); + + // Set up dao + let proposal_single_code_id = app.store_code(proposal_single_contract()); + let dao_addr = instantiate_with_cw4_groups_governance( + &mut app, + proposal_single_code_id, + to_json_binary(&dao_proposal_single::msg::InstantiateMsg { + threshold: Threshold::AbsolutePercentage { + percentage: dao_voting::threshold::PercentageThreshold::Majority {}, + }, + max_voting_period: cw_utils::Duration::Height(10u64), + min_voting_period: None, + only_members_execute: false, + allow_revoting: false, + pre_propose_info: dao_voting::pre_propose::PreProposeInfo::AnyoneMayPropose {}, + close_proposal_on_execution_failure: true, + veto: None, + }) + .unwrap(), + Some(vec![ + Cw20Coin { + address: ADDR1.to_string(), + amount: Uint128::one(), + }, + Cw20Coin { + address: ADDR2.to_string(), + amount: Uint128::one(), + }, + ]), + ); + + // Get proposal single addr + let proposal_modules: Vec = app + .wrap() + .query_wasm_smart( + dao_addr.clone(), + &dao_interface::msg::QueryMsg::ProposalModules { + start_after: None, + limit: Some(1u32), + }, + ) + .unwrap(); + assert!(!proposal_modules.is_empty()); + let proposal_single_addr = proposal_modules.first().unwrap().address.clone(); + + // Set up dao voting incentives code id + let dao_voting_incentives_code_id = app.store_code(dao_voting_incentives_contract()); + + Context { + app, + cw20_addr, + dao_addr, + dao_voting_incentives_code_id, + proposal_single_addr, + } +} + +fn vote_yes_on_proposal(context: &mut Context, proposal_id: u64) -> Vec> { + vec![ + context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &[], + ), + context.app.execute_contract( + Addr::unchecked(ADDR2), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Vote { + proposal_id, + vote: dao_voting::voting::Vote::Yes, + rationale: None, + }, + &[], + ), + ] +} + +fn execute_proposal(context: &mut Context, proposal_id: u64) { + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Execute { proposal_id }, + &[], + ) + .unwrap(); +} + +#[test] +pub fn test_instantiate_validation() { + let mut context = get_context(); + + // Check already expired is error + let result = context.app.instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(1u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ); + assert!(result.is_err()); + + // Check expiration never is error + let result = context.app.instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::Never {}, + }, + &[], + "dao_voting_incentives".to_string(), + None, + ); + assert!(result.is_err()); +} + +#[test] +pub fn test_hooks() { + let mut context = get_context(); + + // Create the voting incentives contract for native + // The expiration is 10 blocks from start (12345 height) + let dao_voting_incentives_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ) + .unwrap(); + + // Also create a parallel voting incentives contract for cw20 + let dao_voting_incentives_cw20_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Cw20(context.cw20_addr.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives_cw20".to_string(), + None, + ) + .unwrap(); + + context.app.update_block(|x| x.height += 1); + + // Execute fails - unauthorized + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::VoteHook(dao_hooks::vote::VoteHookMsg::NewVote { + proposal_id: 1u64, + voter: ADMIN.to_string(), + vote: "a fake vote".to_string(), + }), + &[], + ); + assert!(result.is_err()); + + // Fund the incentives contracts for 1000 + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &[Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + context.cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::Send { + contract: dao_voting_incentives_cw20_addr.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }, + &[], + ); + assert!(result.is_ok()); + + // Assert the cw20 voting incentives do not accept a random cw20 token + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: ADMIN.to_string(), + amount: Uint128::new(1000), + msg: Binary::default(), + }), + &[], + ); + assert!(result.is_err()); + + // Propose adding both hooks + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Add vote hooks".to_string(), + description: "Adding 2 voting hooks to test the dao_voting_incentives contract" + .to_string(), + msgs: vec![ + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddVoteHook { + address: dao_voting_incentives_addr.to_string(), + }) + .unwrap(), + funds: vec![], + }), + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: context.proposal_single_addr.to_string(), + msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddVoteHook { + address: dao_voting_incentives_cw20_addr.to_string(), + }) + .unwrap(), + funds: vec![], + }), + ], + proposer: None, + }), + &[], + ); + assert!(result.is_ok()); + + // Vote and execute the proposal to add the vote hooks + let results = vote_yes_on_proposal(&mut context, 1u64); + for result in results { + assert!(result.is_ok()); + } + execute_proposal(&mut context, 1u64); + + // Query for the newly-established hooks + let result: cw_hooks::HooksResponse = context + .app + .wrap() + .query_wasm_smart( + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::QueryMsg::VoteHooks {}, + ) + .unwrap(); + assert!(result + .hooks + .contains(&dao_voting_incentives_addr.to_string())); + assert!(result + .hooks + .contains(&dao_voting_incentives_cw20_addr.to_string())); + + // Create a new proposal + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &[], + ) + .unwrap(); + + // Trigger a vote hook + let results = vote_yes_on_proposal(&mut context, 2u64); + for result in results { + assert!(result.is_ok()); + } + + // Assert that the vote hook has incremented vote counts + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_addr.clone(), + &QueryMsg::Votes { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_addr.clone(), + &QueryMsg::Votes { + address: ADDR2.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_cw20_addr.clone(), + &QueryMsg::Votes { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let votes: Uint128 = context + .app + .wrap() + .query_wasm_smart( + dao_voting_incentives_cw20_addr.clone(), + &QueryMsg::Votes { + address: ADDR2.to_string(), + }, + ) + .unwrap(); + assert_eq!(votes, Uint128::one()); + let config: Config = context + .app + .wrap() + .query_wasm_smart(dao_voting_incentives_addr.clone(), &QueryMsg::Config {}) + .unwrap(); + assert_eq!(config.total_votes, Uint128::new(2)); + + // Blocks have passed the voting incentives' expirations + context.app.update_block(|x| x.height += 100); + + // Creating another proposal and voting should still succeed but unregister these vote hooks + context + .app + .execute_contract( + Addr::unchecked(ADDR1), + context.proposal_single_addr.clone(), + &dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg { + title: "Test proposal".to_string(), + description: "Testing".to_string(), + msgs: vec![], + proposer: None, + }), + &[], + ) + .unwrap(); + let results = vote_yes_on_proposal(&mut context, 3u64); + for (i, result) in results.iter().enumerate() { + assert!(result.is_ok()); + if i == 0 { + // Vote hooks should unregister on the first instance of expiration + let events = &result.as_ref().unwrap().events; + assert!(events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_vote_hook" + && y.value == format!("{0}:0", dao_voting_incentives_addr.clone())))); + assert!(events.iter().any(|x| x + .attributes + .iter() + .any(|y| y.key == "removed_vote_hook" + && y.value == format!("{0}:1", dao_voting_incentives_cw20_addr.clone())))); + } + } +} + +#[test] +pub fn test_migrate_update_version() { + let mut deps = mock_dependencies(); + cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); + migrate(deps.as_mut(), mock_env(), MigrateMsg::FromCompatible {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); + assert_eq!(version.version, CONTRACT_VERSION); + assert_eq!(version.contract, CONTRACT_NAME); +} diff --git a/packages/dao-testing/Cargo.toml b/packages/dao-testing/Cargo.toml index e8eebb9b9..fa880b4d3 100644 --- a/packages/dao-testing/Cargo.toml +++ b/packages/dao-testing/Cargo.toml @@ -62,4 +62,5 @@ dao-voting-onft-staked = { workspace = true } dao-voting-token-staked = { workspace = true } voting-v1 = { workspace = true } stake-cw20-v03 = { workspace = true } -dao-proposal-incentives = { workspace = true } \ No newline at end of file +dao-proposal-incentives = { workspace = true } +dao-voting-incentives = { workspace = true } \ No newline at end of file diff --git a/packages/dao-testing/src/contracts.rs b/packages/dao-testing/src/contracts.rs index 51ee57df5..082921036 100644 --- a/packages/dao-testing/src/contracts.rs +++ b/packages/dao-testing/src/contracts.rs @@ -222,7 +222,19 @@ pub fn dao_proposal_incentives_contract() -> Box> { dao_proposal_incentives::contract::execute, dao_proposal_incentives::contract::instantiate, dao_proposal_incentives::contract::query, - ); + ) + .with_migrate(dao_proposal_incentives::contract::migrate); + + Box::new(contract) +} + +pub fn dao_voting_incentives_contract() -> Box> { + let contract = ContractWrapper::new( + dao_voting_incentives::contract::execute, + dao_voting_incentives::contract::instantiate, + dao_voting_incentives::contract::query, + ) + .with_migrate(dao_voting_incentives::contract::migrate); Box::new(contract) } From 94196580c25f5d0cc8582fc63c452bc86d5e3322 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Fri, 9 Feb 2024 14:59:33 -0600 Subject: [PATCH 37/47] Fix for simultaneous hook error handling --- .../dao-proposal-multiple/src/contract.rs | 21 +++++++++-- .../dao-proposal-multiple/src/state.rs | 4 +++ .../dao-proposal-single/src/contract.rs | 22 ++++++++++-- .../proposal/dao-proposal-single/src/state.rs | 4 +++ packages/cw-hooks/src/lib.rs | 35 +++++++++++++++++++ 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/contracts/proposal/dao-proposal-multiple/src/contract.rs b/contracts/proposal/dao-proposal-multiple/src/contract.rs index 7f8e5e708..f5125f66c 100644 --- a/contracts/proposal/dao-proposal-multiple/src/contract.rs +++ b/contracts/proposal/dao-proposal-multiple/src/contract.rs @@ -26,6 +26,7 @@ use dao_voting::{ voting::{get_total_power, get_voting_power, validate_voting_period}, }; +use crate::state::{REMOVED_PROPOSAL_HOOKS_BY_INDEX, REMOVED_VOTE_HOOKS_BY_INDEX}; use crate::{msg::MigrateMsg, state::CREATION_POLICY}; use crate::{ msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, @@ -249,6 +250,7 @@ pub fn execute_propose( PROPOSALS.save(deps.storage, id, &proposal)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let hooks = new_proposal_hooks(PROPOSAL_HOOKS, deps.storage, id, proposer.as_str())?; let sender = info.sender.clone(); @@ -343,6 +345,7 @@ pub fn execute_veto( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -437,6 +440,8 @@ pub fn execute_vote( prop.update_status(&env.block)?; PROPOSALS.save(deps.storage, proposal_id, &prop)?; let new_status = prop.status; + + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let change_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -444,6 +449,8 @@ pub fn execute_vote( old_status.to_string(), new_status.to_string(), )?; + + REMOVED_VOTE_HOOKS_BY_INDEX.remove(deps.storage); let vote_hooks = new_vote_hooks( VOTE_HOOKS, deps.storage, @@ -559,6 +566,7 @@ pub fn execute_execute( Response::default() }; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -602,6 +610,7 @@ pub fn execute_close( PROPOSALS.save(deps.storage, proposal_id, &prop)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -1010,11 +1019,19 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - let addr = PROPOSAL_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = PROPOSAL_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_PROPOSAL_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_proposal_hook", format!("{addr}:{idx}"))) } TaggedReplyId::FailedVoteHook(idx) => { - let addr = VOTE_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = VOTE_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_VOTE_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed vote hook", format!("{addr}:{idx}"))) } TaggedReplyId::PreProposeModuleInstantiation => { diff --git a/contracts/proposal/dao-proposal-multiple/src/state.rs b/contracts/proposal/dao-proposal-multiple/src/state.rs index 2261f6d03..26906d5cf 100644 --- a/contracts/proposal/dao-proposal-multiple/src/state.rs +++ b/contracts/proposal/dao-proposal-multiple/src/state.rs @@ -69,6 +69,10 @@ pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("ballots"); pub const PROPOSAL_HOOKS: Hooks = Hooks::new("proposal_hooks"); /// Consumers of vote hooks. pub const VOTE_HOOKS: Hooks = Hooks::new("vote_hooks"); +/// Lists of hook indexes removed to adjust for in submsg replies +pub const REMOVED_VOTE_HOOKS_BY_INDEX: Item> = Item::new("removed_vote_hooks_by_index"); +pub const REMOVED_PROPOSAL_HOOKS_BY_INDEX: Item> = + Item::new("removed_proposal_hooks_by_index"); /// The address of the pre-propose module associated with this /// proposal module (if any). pub const CREATION_POLICY: Item = Item::new("creation_policy"); diff --git a/contracts/proposal/dao-proposal-single/src/contract.rs b/contracts/proposal/dao-proposal-single/src/contract.rs index f2329ecc6..49bf1ae91 100644 --- a/contracts/proposal/dao-proposal-single/src/contract.rs +++ b/contracts/proposal/dao-proposal-single/src/contract.rs @@ -27,7 +27,9 @@ use dao_voting::voting::{get_total_power, get_voting_power, validate_voting_peri use crate::msg::MigrateMsg; use crate::proposal::{next_proposal_id, SingleChoiceProposal}; -use crate::state::{Config, CREATION_POLICY}; +use crate::state::{ + Config, CREATION_POLICY, REMOVED_PROPOSAL_HOOKS_BY_INDEX, REMOVED_VOTE_HOOKS_BY_INDEX, +}; use crate::v1_state::{ v1_duration_to_v2, v1_expiration_to_v2, v1_status_to_v2, v1_threshold_to_v2, v1_votes_to_v2, }; @@ -250,6 +252,7 @@ pub fn execute_propose( PROPOSALS.save(deps.storage, id, &proposal)?; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let hooks = new_proposal_hooks(PROPOSAL_HOOKS, deps.storage, id, proposer.as_str())?; // Auto cast vote if given. @@ -335,6 +338,7 @@ pub fn execute_veto( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -447,6 +451,7 @@ pub fn execute_execute( }; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -543,6 +548,7 @@ pub fn execute_vote( PROPOSALS.save(deps.storage, proposal_id, &prop)?; let new_status = prop.status; + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let change_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -551,6 +557,7 @@ pub fn execute_vote( new_status.to_string(), )?; + REMOVED_VOTE_HOOKS_BY_INDEX.remove(deps.storage); let vote_hooks = new_vote_hooks( VOTE_HOOKS, deps.storage, @@ -624,6 +631,7 @@ pub fn execute_close( PROPOSALS.save(deps.storage, proposal_id, &prop)?; // Add proposal status change hooks + REMOVED_PROPOSAL_HOOKS_BY_INDEX.remove(deps.storage); let proposal_status_changed_hooks = proposal_status_changed_hooks( PROPOSAL_HOOKS, deps.storage, @@ -1094,11 +1102,19 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - let addr = PROPOSAL_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = PROPOSAL_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_PROPOSAL_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_proposal_hook", format!("{addr}:{idx}"))) } TaggedReplyId::FailedVoteHook(idx) => { - let addr = VOTE_HOOKS.remove_hook_by_index(deps.storage, idx)?; + let addr = VOTE_HOOKS.remove_hook_by_index_from_reply( + deps.storage, + idx, + REMOVED_VOTE_HOOKS_BY_INDEX, + )?; Ok(Response::new().add_attribute("removed_vote_hook", format!("{addr}:{idx}"))) } TaggedReplyId::PreProposeModuleInstantiation => { diff --git a/contracts/proposal/dao-proposal-single/src/state.rs b/contracts/proposal/dao-proposal-single/src/state.rs index 88e748b51..55fcf3cb6 100644 --- a/contracts/proposal/dao-proposal-single/src/state.rs +++ b/contracts/proposal/dao-proposal-single/src/state.rs @@ -74,6 +74,10 @@ pub const BALLOTS: Map<(u64, &Addr), Ballot> = Map::new("ballots"); pub const PROPOSAL_HOOKS: Hooks = Hooks::new("proposal_hooks"); /// Consumers of vote hooks. pub const VOTE_HOOKS: Hooks = Hooks::new("vote_hooks"); +/// Lists of hook indexes removed to adjust for in submsg replies +pub const REMOVED_VOTE_HOOKS_BY_INDEX: Item> = Item::new("removed_vote_hooks_by_index"); +pub const REMOVED_PROPOSAL_HOOKS_BY_INDEX: Item> = + Item::new("removed_proposal_hooks_by_index"); /// The address of the pre-propose module associated with this /// proposal module (if any). pub const CREATION_POLICY: Item = Item::new("creation_policy"); diff --git a/packages/cw-hooks/src/lib.rs b/packages/cw-hooks/src/lib.rs index fdbf43577..6f08a497d 100644 --- a/packages/cw-hooks/src/lib.rs +++ b/packages/cw-hooks/src/lib.rs @@ -102,6 +102,41 @@ impl<'a> Hooks<'a> { let hooks = hooks.into_iter().map(String::from).collect(); Ok(HooksResponse { hooks }) } + + /// Use this method to remove a hook by index from a reply + /// The removed_hook_indexes should be cleared when submsgs are sent + pub fn remove_hook_by_index_from_reply( + &self, + storage: &mut dyn Storage, + index: u64, + removed_hook_indexes: Item>, + ) -> Result { + let adjusted_index = match removed_hook_indexes.may_load(storage)? { + Some(mut removed_indexes) => { + let mut result = index; + + for removed_index in removed_indexes.iter() { + if removed_index < &index { + result -= 1; + } + } + + // Update the removed indexes + removed_indexes.push(index); + removed_hook_indexes.save(storage, &removed_indexes)?; + + result + } + None => { + // Set the removed indexes + removed_hook_indexes.save(storage, &vec![index])?; + + index + } + }; + + self.remove_hook_by_index(storage, adjusted_index) + } } #[cfg(test)] From 6961ce6ccd4911ae1845f4aa6ce613609ed2efb6 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Sat, 10 Feb 2024 15:31:30 -0600 Subject: [PATCH 38/47] Wrap up tests for voting incentives --- Cargo.lock | 1 - .../dao-voting-incentives/src/error.rs | 3 + .../dao-voting-incentives/src/execute.rs | 5 + .../dao-voting-incentives/src/state.rs | 2 +- .../dao-voting-incentives/src/tests.rs | 141 +++++++++++++++++- .../proposal/dao-proposal-single/Cargo.toml | 1 - 6 files changed, 149 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbc58e3b6..0766e9ed9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2196,7 +2196,6 @@ dependencies = [ "dao-interface 2.5.0", "dao-pre-propose-base 2.5.0", "dao-pre-propose-single 2.5.0", - "dao-proposal-incentives", "dao-testing", "dao-voting 0.1.0", "dao-voting 2.5.0", diff --git a/contracts/external/dao-voting-incentives/src/error.rs b/contracts/external/dao-voting-incentives/src/error.rs index 15b5024ad..64b3298b3 100644 --- a/contracts/external/dao-voting-incentives/src/error.rs +++ b/contracts/external/dao-voting-incentives/src/error.rs @@ -38,4 +38,7 @@ pub enum ContractError { expected: CheckedDenom, received: CheckedDenom, }, + + #[error("NothingToClaim")] + NothingToClaim {}, } diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index bed6fe22f..22a16935b 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -14,6 +14,11 @@ use crate::{ }; pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { + // Ensure the user has something to claim + if !USER_VOTE_COUNT.has(deps.storage, &info.sender) { + return Err(ContractError::NothingToClaim {}); + } + // Get reward information let reward = reward(deps.as_ref(), &info.sender)?; diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 14ac95b50..09fdbfbac 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -87,5 +87,5 @@ fn calculate_reward( return Ok(Uint128::zero()); } - balance.checked_div_floor((user_votes, total_votes)) + balance.checked_mul_floor((user_votes, total_votes)) } diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index de63a8419..2f9f0c531 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg, }; -use cw20::{Cw20Coin, Cw20ReceiveMsg}; +use cw20::{BalanceResponse, Cw20Coin, Cw20QueryMsg, Cw20ReceiveMsg}; use cw_denom::UncheckedDenom; use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor}; use cw_utils::Expiration; @@ -457,6 +457,145 @@ pub fn test_hooks() { && y.value == format!("{0}:1", dao_voting_incentives_cw20_addr.clone())))); } } + + // Expire the vote hooks + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + + // Ensure expire errors if already expired + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_err()); + + // Random person cannot claim + let result = context.app.execute_contract( + Addr::unchecked("random"), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_err()); + + // User claims rewards + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_ok()); + + // User balance has increased by 500, because 1000 reward with 2 voters during the period + let balance = context + .app + .wrap() + .query_balance(Addr::unchecked(ADDR1), DENOM) + .unwrap(); + assert_eq!(balance.amount, Uint128::new(500)); + + // User cannot claim again + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_err()); + + // User claims rewards cw20 + let result = context.app.execute_contract( + Addr::unchecked(ADDR1), + dao_voting_incentives_cw20_addr.clone(), + &ExecuteMsg::Claim {}, + &[], + ); + assert!(result.is_ok()); + + // User balance has increased by 500, because 1000 reward with 2 voters during the period + let balance_response: BalanceResponse = context + .app + .wrap() + .query_wasm_smart( + context.cw20_addr, + &Cw20QueryMsg::Balance { + address: ADDR1.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance_response.balance, Uint128::new(500)); +} + +#[test] +pub fn test_expire_sends_funds_to_owner() { + let mut context = get_context(); + + // Create the voting incentives contract for native + // The expiration is 10 blocks from start (12345 height) + let dao_voting_incentives_addr = context + .app + .instantiate_contract( + context.dao_voting_incentives_code_id, + Addr::unchecked(ADMIN), + &InstantiateMsg { + owner: context.dao_addr.to_string(), + denom: UncheckedDenom::Native(DENOM.to_string()), + expiration: Expiration::AtHeight(12355u64), + }, + &[], + "dao_voting_incentives".to_string(), + None, + ) + .unwrap(); + + // Fund the incentives contracts for 1000 + context + .app + .send_tokens( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &[Coin { + denom: DENOM.to_string(), + amount: Uint128::new(1000), + }], + ) + .unwrap(); + + // Blocks have passed the voting incentives' expirations + context.app.update_block(|x| x.height += 100); + + // Expire the vote hooks + // No votes were received during the period, so the funds should be sent to the owner on expiration + let result = context.app.execute_contract( + Addr::unchecked(ADMIN), + dao_voting_incentives_addr.clone(), + &ExecuteMsg::Expire {}, + &[], + ); + assert!(result.is_ok()); + + // Ensure funds were sent to the DAO + let balance = context + .app + .wrap() + .query_balance(context.dao_addr, DENOM) + .unwrap(); + assert_eq!(balance.amount, Uint128::new(1000)); } #[test] diff --git a/contracts/proposal/dao-proposal-single/Cargo.toml b/contracts/proposal/dao-proposal-single/Cargo.toml index 6bc126fa9..06170dd00 100644 --- a/contracts/proposal/dao-proposal-single/Cargo.toml +++ b/contracts/proposal/dao-proposal-single/Cargo.toml @@ -54,4 +54,3 @@ cw721-base = { workspace = true } cw4 = { workspace = true } cw4-group = { workspace = true } cw-core-v1 = { workspace = true, features = ["library"] } -dao-proposal-incentives = { workspace = true } From 809ba2c29d30de1dbbe03fd81ee04d5e2425dcb0 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 13 Feb 2024 08:59:15 -0600 Subject: [PATCH 39/47] Combine rewards queries --- .../schema/dao-voting-incentives.json | 114 ++++++++---------- .../dao-voting-incentives/src/contract.rs | 5 +- .../dao-voting-incentives/src/execute.rs | 9 +- .../external/dao-voting-incentives/src/msg.rs | 5 +- .../dao-voting-incentives/src/query.rs | 10 +- .../dao-voting-incentives/src/state.rs | 47 +++----- 6 files changed, 77 insertions(+), 113 deletions(-) diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index 0bfbb8c10..70ef14eda 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -183,6 +183,18 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "receive" + ], + "properties": { + "receive": { + "$ref": "#/definitions/Cw20ReceiveMsg" + } + }, + "additionalProperties": false } ], "definitions": { @@ -237,6 +249,31 @@ } ] }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Cw20ReceiveMsg": { + "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", + "type": "object", + "required": [ + "amount", + "msg", + "sender" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "sender": { + "type": "string" + } + }, + "additionalProperties": false + }, "Expiration": { "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", "oneOf": [ @@ -292,6 +329,10 @@ } ] }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, "Uint64": { "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", "type": "string" @@ -353,7 +394,7 @@ "additionalProperties": false }, { - "description": "Returns the claimable rewards for the given address.", + "description": "Returns the rewards for the given address.", "type": "object", "required": [ "rewards" @@ -375,13 +416,13 @@ "additionalProperties": false }, { - "description": "Returns the expected rewards for the given address", + "description": "Returns the votes count for the given address", "type": "object", "required": [ - "expected_rewards" + "votes" ], "properties": { - "expected_rewards": { + "votes": { "type": "object", "required": [ "address" @@ -478,65 +519,6 @@ }, "additionalProperties": false }, - "expected_rewards": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RewardResponse", - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "$ref": "#/definitions/CheckedDenom" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "CheckedDenom": { - "description": "A denom that has been checked to point to a valid asset. This enum should never be constructed literally and should always be built by calling `into_checked` on an `UncheckedDenom` instance.", - "oneOf": [ - { - "description": "A native (bank module) asset.", - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "A cw20 asset.", - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, "ownership": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Ownership_for_String", @@ -690,6 +672,12 @@ "type": "string" } } + }, + "votes": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Uint128", + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" } } } diff --git a/contracts/external/dao-voting-incentives/src/contract.rs b/contracts/external/dao-voting-incentives/src/contract.rs index 75d5b6050..ec439fe57 100644 --- a/contracts/external/dao-voting-incentives/src/contract.rs +++ b/contracts/external/dao-voting-incentives/src/contract.rs @@ -81,10 +81,7 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, address)?), - QueryMsg::ExpectedRewards { address } => { - to_json_binary(&query::expected_rewards(deps, env, address)?) - } + QueryMsg::Rewards { address } => to_json_binary(&query::rewards(deps, env, address)?), QueryMsg::Config {} => to_json_binary(&query::config(deps)?), QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?), QueryMsg::Votes { address } => to_json_binary(&query::votes(deps, address)?), diff --git a/contracts/external/dao-voting-incentives/src/execute.rs b/contracts/external/dao-voting-incentives/src/execute.rs index 22a16935b..a4d312467 100644 --- a/contracts/external/dao-voting-incentives/src/execute.rs +++ b/contracts/external/dao-voting-incentives/src/execute.rs @@ -13,14 +13,14 @@ use crate::{ ContractError, }; -pub fn claim(deps: DepsMut, _env: Env, info: MessageInfo) -> Result { +pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> Result { // Ensure the user has something to claim if !USER_VOTE_COUNT.has(deps.storage, &info.sender) { return Err(ContractError::NothingToClaim {}); } // Get reward information - let reward = reward(deps.as_ref(), &info.sender)?; + let reward = reward(deps.as_ref(), &env.contract.address, &info.sender)?; // If the user has rewards, then we should generate a message let mut msgs = vec![]; @@ -212,13 +212,16 @@ pub fn expire(deps: DepsMut, env: Env, _info: MessageInfo) -> Result Result { let config = CONFIG.load(deps.storage)?; // Do not accept unexpected cw20 + if config.expiration.is_expired(&env.block) { + return Err(ContractError::AlreadyExpired {}); + } match &config.denom { CheckedDenom::Native(_) => { return Err(ContractError::UnexpectedFunds { diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 4eb0b7af4..2b21e0711 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -36,12 +36,9 @@ pub enum QueryMsg { /// Returns the config #[returns(Config)] Config {}, - /// Returns the claimable rewards for the given address. + /// Returns the rewards for the given address. #[returns(RewardResponse)] Rewards { address: String }, - /// Returns the expected rewards for the given address - #[returns(RewardResponse)] - ExpectedRewards { address: String }, /// Returns the votes count for the given address #[returns(Uint128)] Votes { address: String }, diff --git a/contracts/external/dao-voting-incentives/src/query.rs b/contracts/external/dao-voting-incentives/src/query.rs index dcee2772f..622180c2e 100644 --- a/contracts/external/dao-voting-incentives/src/query.rs +++ b/contracts/external/dao-voting-incentives/src/query.rs @@ -5,16 +5,10 @@ use crate::{ state::{self, Config, CONFIG, USER_VOTE_COUNT}, }; -pub fn rewards(deps: Deps, address: String) -> StdResult { +pub fn rewards(deps: Deps, env: Env, address: String) -> StdResult { let address = deps.api.addr_validate(&address)?; - state::reward(deps, &address).map_err(|x| StdError::GenericErr { msg: x.to_string() }) -} - -pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult { - let address = deps.api.addr_validate(&address)?; - - state::expected_reward(deps, env, &address) + state::reward(deps, &env.contract.address, &address) .map_err(|x| StdError::GenericErr { msg: x.to_string() }) } diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 09fdbfbac..3563e38f6 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Env, Uint128}; +use cosmwasm_std::{Addr, CheckedMultiplyFractionError, Deps, Uint128}; use cw_denom::CheckedDenom; use cw_storage_plus::{Item, Map}; use cw_utils::Expiration; @@ -34,15 +34,25 @@ pub const GENERIC_PROPOSAL_INFO: Map<(&Addr, u64), GenericProposalInfo> = Map::new("generic_proposal_info"); /// A method to load reward information -pub fn reward(deps: Deps, addr: &Addr) -> Result { +pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result { let config = CONFIG.load(deps.storage)?; + // Get the user's votes + let user_votes = USER_VOTE_COUNT + .may_load(deps.storage, addr)? + .unwrap_or_default(); + match config.expiration_balance { Some(balance) => { - // Get the user's votes - let user_votes = USER_VOTE_COUNT - .may_load(deps.storage, addr)? - .unwrap_or_default(); + // Calculate the reward + Ok(RewardResponse { + denom: config.denom, + amount: calculate_reward(config.total_votes, user_votes, balance)?, + }) + } + None => { + // Get the current voting incentives balance + let balance = config.denom.query_balance(&deps.querier, contract)?; // Calculate the reward Ok(RewardResponse { @@ -50,34 +60,9 @@ pub fn reward(deps: Deps, addr: &Addr) -> Result amount: calculate_reward(config.total_votes, user_votes, balance)?, }) } - None => Err(ContractError::NotExpired { - expiration: config.expiration, - }), } } -/// A method to load the expected reward information -/// The expected reward method can differ from the actual reward, because the balance is saved in state after expiration -pub fn expected_reward(deps: Deps, env: Env, addr: &Addr) -> Result { - let config = CONFIG.load(deps.storage)?; - - // Get the voting incentives balance - let balance = config - .denom - .query_balance(&deps.querier, &env.contract.address)?; - - // Get the user's votes - let user_votes = USER_VOTE_COUNT - .may_load(deps.storage, addr)? - .unwrap_or_default(); - - // Calculate the reward - Ok(RewardResponse { - denom: config.denom, - amount: calculate_reward(config.total_votes, user_votes, balance)?, - }) -} - fn calculate_reward( total_votes: Uint128, user_votes: Uint128, From 1d5bd35d6ac9b52e7bfd237ea678e5fb9c8eeb87 Mon Sep 17 00:00:00 2001 From: Gabriel Lopez Date: Tue, 13 Feb 2024 21:16:50 -0600 Subject: [PATCH 40/47] Add is_claimable flag to reward response --- .../schema/dao-voting-incentives.json | 6 ++++- .../external/dao-voting-incentives/src/msg.rs | 1 + .../dao-voting-incentives/src/state.rs | 2 ++ .../dao-voting-incentives/src/tests.rs | 24 +++++++++++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index 70ef14eda..f2331d18e 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -620,7 +620,8 @@ "type": "object", "required": [ "amount", - "denom" + "denom", + "is_claimable" ], "properties": { "amount": { @@ -628,6 +629,9 @@ }, "denom": { "$ref": "#/definitions/CheckedDenom" + }, + "is_claimable": { + "type": "boolean" } }, "additionalProperties": false, diff --git a/contracts/external/dao-voting-incentives/src/msg.rs b/contracts/external/dao-voting-incentives/src/msg.rs index 2b21e0711..72b1a6dd6 100644 --- a/contracts/external/dao-voting-incentives/src/msg.rs +++ b/contracts/external/dao-voting-incentives/src/msg.rs @@ -53,4 +53,5 @@ pub enum MigrateMsg { pub struct RewardResponse { pub denom: CheckedDenom, pub amount: Uint128, + pub is_claimable: bool, } diff --git a/contracts/external/dao-voting-incentives/src/state.rs b/contracts/external/dao-voting-incentives/src/state.rs index 3563e38f6..7688ce408 100644 --- a/contracts/external/dao-voting-incentives/src/state.rs +++ b/contracts/external/dao-voting-incentives/src/state.rs @@ -48,6 +48,7 @@ pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result { @@ -58,6 +59,7 @@ pub fn reward(deps: Deps, contract: &Addr, addr: &Addr) -> Result Date: Tue, 7 May 2024 20:54:10 -0500 Subject: [PATCH 41/47] Schemas and clippy fixes --- .../dao-dao-core/schema/dao-dao-core.json | 69 +++++++++++++++++++ .../dao-proposal-incentives/Cargo.toml | 2 +- .../schema/dao-proposal-incentives.json | 2 +- .../dao-proposal-incentives/src/tests.rs | 3 + .../external/dao-voting-incentives/Cargo.toml | 2 +- .../schema/dao-voting-incentives.json | 2 +- .../dao-voting-incentives/src/tests.rs | 3 + .../schema/dao-proposal-condorcet.json | 50 ++++++++++++++ .../schema/dao-proposal-multiple.json | 50 ++++++++++++++ .../schema/dao-proposal-single.json | 50 ++++++++++++++ 10 files changed, 229 insertions(+), 4 deletions(-) diff --git a/contracts/dao-dao-core/schema/dao-dao-core.json b/contracts/dao-dao-core/schema/dao-dao-core.json index b1cca4f3d..c894c9f69 100644 --- a/contracts/dao-dao-core/schema/dao-dao-core.json +++ b/contracts/dao-dao-core/schema/dao-dao-core.json @@ -1796,6 +1796,27 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "proposal_module" + ], + "properties": { + "proposal_module": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Gets the active proposal modules associated with the contract.", "type": "object", @@ -3033,6 +3054,54 @@ } } }, + "proposal_module": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ProposalModule", + "description": "Top level type describing a proposal module.", + "type": "object", + "required": [ + "address", + "prefix", + "status" + ], + "properties": { + "address": { + "description": "The address of the proposal module.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "prefix": { + "description": "The URL prefix of this proposal module as derived from the module ID. Prefixes are mapped to letters, e.g. 0 is 'A', and 26 is 'AA'.", + "type": "string" + }, + "status": { + "description": "The status of the proposal module, e.g. 'Enabled' or 'Disabled.'", + "allOf": [ + { + "$ref": "#/definitions/ProposalModuleStatus" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "ProposalModuleStatus": { + "description": "The status of a proposal module.", + "type": "string", + "enum": [ + "enabled", + "disabled" + ] + } + } + }, "proposal_module_count": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ProposalModuleCountResponse", diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index ff3827b82..a347bf3f2 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-proposal-incentives" -authors = ["Jake Hartnell ", "ismellike"] +authors = ["Jake Hartnell ", "Gabe Lopez "] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } diff --git a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json index 2d02b5883..a258c15ea 100644 --- a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json +++ b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-proposal-incentives", - "contract_version": "2.4.0", + "contract_version": "2.4.2", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/contracts/external/dao-proposal-incentives/src/tests.rs b/contracts/external/dao-proposal-incentives/src/tests.rs index 2adca6808..903ef94df 100644 --- a/contracts/external/dao-proposal-incentives/src/tests.rs +++ b/contracts/external/dao-proposal-incentives/src/tests.rs @@ -357,6 +357,7 @@ pub fn test_hook() { funds: vec![], })], proposer: None, + vote: None, }), &[], ); @@ -390,6 +391,7 @@ pub fn test_hook() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) @@ -418,6 +420,7 @@ pub fn test_hook() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index be6d63c19..882d4a7ab 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-voting-incentives" -authors = ["Jake Hartnell ", "ismellike"] +authors = ["Jake Hartnell ", "Gabe Lopez "] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index f2331d18e..08eefdf57 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-voting-incentives", - "contract_version": "2.4.0", + "contract_version": "2.4.2", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/contracts/external/dao-voting-incentives/src/tests.rs b/contracts/external/dao-voting-incentives/src/tests.rs index d4058e61f..a6fb3ebb6 100644 --- a/contracts/external/dao-voting-incentives/src/tests.rs +++ b/contracts/external/dao-voting-incentives/src/tests.rs @@ -319,6 +319,7 @@ pub fn test_hooks() { }), ], proposer: None, + vote: None, }), &[], ); @@ -358,6 +359,7 @@ pub fn test_hooks() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) @@ -435,6 +437,7 @@ pub fn test_hooks() { description: "Testing".to_string(), msgs: vec![], proposer: None, + vote: None, }), &[], ) diff --git a/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json b/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json index 31094252c..c64822ef6 100644 --- a/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json +++ b/contracts/proposal/dao-proposal-condorcet/schema/dao-proposal-condorcet.json @@ -1239,6 +1239,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -1355,6 +1379,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "info": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "InfoResponse", diff --git a/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json b/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json index 75729fda4..355379b3a 100644 --- a/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json +++ b/contracts/proposal/dao-proposal-multiple/schema/dao-proposal-multiple.json @@ -2177,6 +2177,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -2679,6 +2703,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "get_vote": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "VoteResponse", diff --git a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json index 9738cadec..b06e82b80 100644 --- a/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json +++ b/contracts/proposal/dao-proposal-single/schema/dao-proposal-single.json @@ -2255,6 +2255,30 @@ } }, "additionalProperties": false + }, + { + "description": "Returns generic proposal information", + "type": "object", + "required": [ + "generic_proposal_info" + ], + "properties": { + "generic_proposal_info": { + "type": "object", + "required": [ + "proposal_id" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -2810,6 +2834,32 @@ "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", "type": "string" }, + "generic_proposal_info": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GenericProposalInfo", + "type": "object", + "required": [ + "proposer", + "start_height" + ], + "properties": { + "proposer": { + "$ref": "#/definitions/Addr" + }, + "start_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "get_vote": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "VoteResponse", From 4a9a9e195fdb5fc5606542278affd0dd7eee99e7 Mon Sep 17 00:00:00 2001 From: ismellike Date: Thu, 13 Jun 2024 10:24:30 -0500 Subject: [PATCH 42/47] Update contracts/external/dao-proposal-incentives/Cargo.toml Co-authored-by: Jake Hartnell --- contracts/external/dao-proposal-incentives/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index a347bf3f2..73ba15581 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="dao-proposal-incentives" authors = ["Jake Hartnell ", "Gabe Lopez "] -description = "A contract that implements incentives for voting in a DAO." +description = "A contract that implements incentives for creating a successful proposal in a DAO." edition = { workspace = true } license = { workspace = true } repository = { workspace = true } From 778a361ef07d26cf83b155ef15cdb3e61a30980b Mon Sep 17 00:00:00 2001 From: ismellike Date: Thu, 15 Aug 2024 21:16:29 -0500 Subject: [PATCH 43/47] Improve proposal & voting incentives readme's + add not audited warnings --- .../dao-proposal-incentives/README.md | 65 +++++++++++----- .../external/dao-voting-incentives/README.md | 74 +++++++++++++------ 2 files changed, 98 insertions(+), 41 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/README.md b/contracts/external/dao-proposal-incentives/README.md index 45bd9e0db..508406e1c 100644 --- a/contracts/external/dao-proposal-incentives/README.md +++ b/contracts/external/dao-proposal-incentives/README.md @@ -1,31 +1,60 @@ # dao-proposal-incentives -[![dao-proposal-incentives on crates.io](https://img.shields.io/crates/v/dao-proposal-incentives.svg?logo=rust)](https://crates.io/crates/dao-proposal-incentives) -[![docs.rs](https://img.shields.io/docsrs/dao-proposal-incentives?logo=docsdotrs)](https://docs.rs/dao-proposal-incentives/latest/cw_admin_factory/) +> **WARNING:** THIS CONTRACT IS NOT AUDITED AND IS EXPERIMENTAL. USE AT YOUR OWN RISK. -This contract enables DAO's to incentivize members for making successful proposals. By integrating this contract, DAO's can automatically reward members whose proposals are successfully passed, using either native tokens or CW20 tokens. +## Overview -## Instantiate +The `dao-proposal-incentives` contract empowers DAOs to boost member engagement by automatically rewarding successful proposals. This approach encourages active participation and high-quality contributions to DAO governance. -To instantiate the contract, provide the following parameters: +### Key Features -- `owner`: The DAO sending this contract proposal hooks. -- `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure. +- Automatic rewards for passed proposals +- Support for both native and CW20 tokens +- Dynamic incentive adjustment +- Seamless integration with existing DAO modules -## Configuration +## How It Works -- This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules. -- The DAO must be set as the `owner` of this contract to manage incentives and ownership. +1. **Setup**: The DAO instantiates the contract and sets initial reward parameters. +2. **Funding**: The contract is funded with tokens for rewards. +2. **Integration**: The contract is added as a proposal hook to the DAO's voting module. +3. **Proposal Lifecycle**: When a proposal passes, the contract automatically rewards the proposer. +4. **Flexible Management**: The DAO can adjust reward amounts and token types as needed. -The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources. +## Usage Guide -## Execute +### Instantiation -- **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals. -- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. -- **UpdateProposalIncentives { proposal_incentives: ProposalIncentivesUnchecked }**: Updates the incentives configuration. This allows the DAO to modify the rewards for successful proposals. -- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. +To set up the contract, provide: -## Query +- `owner`: The DAO's address (for sending proposal hooks) +- `proposal_incentives`: Reward configuration using `ProposalIncentivesUnchecked` -- **ProposalIncentives { height: Option }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time. +Example: +```rust +let msg = InstantiateMsg { + owner: "dao_address".to_string(), + proposal_incentives: ProposalIncentivesUnchecked { + rewards_per_proposal: Uint128::new(1000), + denom: UncheckedDenom::Native("ujuno".to_string()), + }, +}; +``` + +### Configuration + +1. Add this contract as a `ProposalHook` to your DAO's voting module (`dao-voting-single` or `dao-voting-multiple`). +2. Ensure the DAO is set as the contract `owner` for proper management. + +### Key Functions + +#### Execute Messages + +1. **ProposalHook(ProposalHookMsg)**: Handles proposal status changes and reward distribution. +2. **UpdateOwnership(cw_ownable::Action)**: Manages contract ownership. +3. **UpdateProposalIncentives**: Allows the DAO to modify reward settings. +4. **Receive(Cw20ReceiveMsg)**: Processes incoming CW20 tokens for rewards. + +#### Query Messages + +- **ProposalIncentives { height: Option }**: Retrieves current or historical incentive configurations. \ No newline at end of file diff --git a/contracts/external/dao-voting-incentives/README.md b/contracts/external/dao-voting-incentives/README.md index 645fcb2b2..aa9c1a0d3 100644 --- a/contracts/external/dao-voting-incentives/README.md +++ b/contracts/external/dao-voting-incentives/README.md @@ -1,37 +1,65 @@ # dao-voting-incentives -[![dao-voting-incentives on crates.io](https://img.shields.io/crates/v/dao-voting-incentives.svg?logo=rust)](https://crates.io/crates/dao-voting-incentives) -[![docs.rs](https://img.shields.io/docsrs/dao-voting-incentives?logo=docsdotrs)](https://docs.rs/dao-voting-incentives/latest/cw_admin_factory/) +> **WARNING:** THIS CONTRACT IS NOT AUDITED AND IS EXPERIMENTAL. USE AT YOUR OWN RISK. -This contract enables DAOs to offer incentives for voting on DAO proposals. By rewarding active voters, DAOs can encourage greater community involvement and decision-making. +The `dao-voting-incentives` contract is designed to boost participation in DAO governance by offering rewards for voting on proposals. This innovative mechanism encourages active community involvement and more representative decision-making within DAOs. -## Instantiate +## Features -To instantiate the contract, provide the following parameters: +- Flexible reward distribution for both native and CW20 tokens +- Time-bound incentive periods +- Fair reward calculation based on voting activity -- `owner`: The DAO sending this contract voting hooks. -- `denom`: The denomination of the tokens to distribute as rewards. -- `expiration`: The expiration of the voting incentives period, defining how long the incentives are active. +## Instantiation -## Configuration +To deploy the contract, provide the following parameters: -- This contract should be added as a `VoteHook` to either the `dao-proposal-single` or `dao-proposal-multiple` proposal modules. -- The DAO must be set as the `owner` of this contract to manage incentives and ownership. +```rust +pub struct InstantiateMsg { + pub owner: String, + pub denom: UncheckedDenom, + pub expiration: Expiration, +} +``` -If no votes are cast during the voting incentives period, then the contract's funds are sent to the `owner` on expiration. +- `owner`: The DAO address that will manage the contract and receive vote hooks +- `denom`: The token denomination (native or CW20) to be distributed as rewards +- `expiration`: The end date of the voting incentives period -Rewards for a user are determined as such: `reward(user) = votes(user) * contract's balance / total votes` +## Setup -## Execute +1. Deploy the `dao-voting-incentives` contract +2. Add the contract's address as a `VoteHook` to your DAO's proposal module (`dao-proposal-single` or `dao-proposal-multiple`) +3. Ensure the DAO is set as the `owner` of the contract +4. Fund the contract with the specified reward tokens -- **VoteHook(VoteHookMsg)**: Triggered when a new vote is cast. This is used to track voting activity and allocate rewards accordingly. -- **Claim {}**: Allows voters to claim their rewards after expiration. -- **Expire {}**: Expires the voting incentives period, allowing voters to claim rewards. -- **UpdateOwnership(cw_ownable::Action)**: Updates the ownership of the contract. This can be used to transfer ownership or perform other ownership-related actions. -- **Receive(Cw20ReceiveMsg)**: Handles the receipt of CW20 tokens. This is necessary for managing CW20-based incentives. +## Key Functions -## Query +### Execute Messages -- **Config {}**: Returns the configuration of the voting incentives. -- **Rewards { address: String }**: Queries the claimable rewards for a specific address. -- **ExpectedRewards { address: String }**: Estimates the expected rewards for a specific address, based on current votes. +- `VoteHook(VoteHookMsg)`: Tracks voting activity (automatically called by the proposal module) +- `Claim {}`: Allows voters to claim their earned rewards after the incentive period ends +- `Expire {}`: Finalizes the incentive period, enabling reward claims +- `UpdateOwnership(Action)`: Manages contract ownership +- `Receive(Cw20ReceiveMsg)`: Handles incoming CW20 tokens for rewards + +### Query Messages + +- `Config {}`: Retrieves the contract's configuration +- `Rewards { address: String }`: Gets the claimable rewards for a specific address +- `Votes { address: String }`: Returns the number of votes cast by an address + +## Reward Calculation + +Rewards are calculated using the following formula: + +``` +reward(user) = votes(user) * contract_balance / total_votes +``` + +This ensures a fair distribution based on each user's voting activity relative to the total participation. + +## Important Notes + +- If no votes are cast during the incentive period, all funds are returned to the owner (DAO) upon expiration +- Rewards can only be claimed after the incentive period has ended \ No newline at end of file From 7cce5b3d2579365606e3ca19c7633b474c877bd2 Mon Sep 17 00:00:00 2001 From: ismellike Date: Fri, 16 Aug 2024 01:47:11 -0500 Subject: [PATCH 44/47] gen schema --- .../dao-proposal-incentives/schema/dao-proposal-incentives.json | 2 +- .../dao-voting-incentives/schema/dao-voting-incentives.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json index a258c15ea..8af2e06a5 100644 --- a/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json +++ b/contracts/external/dao-proposal-incentives/schema/dao-proposal-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-proposal-incentives", - "contract_version": "2.4.2", + "contract_version": "2.5.0", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json index 08eefdf57..b936123b4 100644 --- a/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json +++ b/contracts/external/dao-voting-incentives/schema/dao-voting-incentives.json @@ -1,6 +1,6 @@ { "contract_name": "dao-voting-incentives", - "contract_version": "2.4.2", + "contract_version": "2.5.0", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", From 754442daa8d7fd00888bb20a947f16012b664668 Mon Sep 17 00:00:00 2001 From: ismellike Date: Fri, 16 Aug 2024 02:22:01 -0500 Subject: [PATCH 45/47] Disable doctests on gov-incentives --- contracts/external/dao-proposal-incentives/Cargo.toml | 3 ++- contracts/external/dao-voting-incentives/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/external/dao-proposal-incentives/Cargo.toml b/contracts/external/dao-proposal-incentives/Cargo.toml index 73ba15581..5831b3c1b 100644 --- a/contracts/external/dao-proposal-incentives/Cargo.toml +++ b/contracts/external/dao-proposal-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-proposal-incentives" -authors = ["Jake Hartnell ", "Gabe Lopez "] +authors = ["Jake Hartnell ", "Gabe "] description = "A contract that implements incentives for creating a successful proposal in a DAO." edition = { workspace = true } license = { workspace = true } @@ -9,6 +9,7 @@ version = { workspace = true } [lib] crate-type = ["cdylib", "rlib"] +doctest = false [features] # for more explicit tests, cargo test --features=backtraces diff --git a/contracts/external/dao-voting-incentives/Cargo.toml b/contracts/external/dao-voting-incentives/Cargo.toml index 882d4a7ab..925456573 100644 --- a/contracts/external/dao-voting-incentives/Cargo.toml +++ b/contracts/external/dao-voting-incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="dao-voting-incentives" -authors = ["Jake Hartnell ", "Gabe Lopez "] +authors = ["Jake Hartnell ", "Gabe "] description = "A contract that implements incentives for voting in a DAO." edition = { workspace = true } license = { workspace = true } @@ -9,6 +9,7 @@ version = { workspace = true } [lib] crate-type = ["cdylib", "rlib"] +doctest = false [features] # for more explicit tests, cargo test --features=backtraces From ffe92b1d11659aa5084953763cf7f89ca68b215d Mon Sep 17 00:00:00 2001 From: ismellike Date: Fri, 16 Aug 2024 14:35:14 -0500 Subject: [PATCH 46/47] Bump integration_tests to nightly toolchain --- .github/workflows/integration_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 42af0ab81..66119a9f8 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -21,7 +21,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2023-02-02 + toolchain: nightly target: wasm32-unknown-unknown override: true From c3b63217a95bd6f3ffb61096bbc8fce0ed554347 Mon Sep 17 00:00:00 2001 From: ismellike Date: Fri, 16 Aug 2024 14:39:15 -0500 Subject: [PATCH 47/47] Free up space for test_tube.yml https://github.com/DA0-DA0/dao-contracts/pull/876/commits/a9efb44abb104778790cf16f012ec2710a59ff46 --- .github/workflows/test_tube.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/test_tube.yml b/.github/workflows/test_tube.yml index 3b1a584cb..909a8c839 100644 --- a/.github/workflows/test_tube.yml +++ b/.github/workflows/test_tube.yml @@ -17,6 +17,19 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 + # https://github.com/orgs/community/discussions/25678 + - name: Free up disk space on runner + run: | + df -h + rm -rf /usr/share/dotnet/ + sudo apt-get remove -y 'php.*' + sudo apt-get remove -y '^dotnet-.*' + sudo apt-get remove -y azure-cli firefox powershell mono-devel + sudo apt-get autoremove -y + sudo apt-get clean + df -h + shell: bash + - name: Install latest nightly toolchain uses: actions-rs/toolchain@v1 with: