From 388654590779247e8154c4c90021646b786302f1 Mon Sep 17 00:00:00 2001 From: Pham Tu Date: Thu, 7 Mar 2024 11:29:30 +0700 Subject: [PATCH] fix is_member --- contracts/cw3-flex-multisig/src/contract.rs | 47 ++++++--------------- contracts/cw3-flex-multisig/src/state.rs | 11 +++-- packages/cw4/src/helpers.rs | 26 +++++++++--- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 4320ab9e4..96456b00c 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -3,8 +3,8 @@ use std::cmp::Ordering; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, Api, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, - MessageInfo, Order, QuerierWrapper, Response, StdResult, Storage, + to_json_binary, Binary, BlockInfo, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, + Response, StdResult, }; use cw2::set_contract_version; @@ -14,8 +14,8 @@ use cw3::{ VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, Votes, }; use cw3_fixed_multisig::state::next_id; -use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff, MEMBERS_KEY}; -use cw_storage_plus::{Bound, Map}; +use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; +use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Duration, Expiration, Threshold, ThresholdResponse}; use crate::error::ContractError; @@ -151,7 +151,9 @@ pub fn execute_propose( // therefore "vote", but they aren't allowed to vote otherwise. // Such vote is also special, because despite having 0 weight it still counts when // counting threshold passing - let vote_power = is_member(deps.storage, &deps.querier, deps.api, &info.sender, None)? + let vote_power = cfg + .group_addr + .is_member(&deps.querier, deps.api, &info.sender, None)? .ok_or(ContractError::Unauthorized {})?; // max expires also used as default @@ -271,7 +273,7 @@ pub fn execute_execute( } let cfg = CONFIG.load(deps.storage)?; - cfg.authorize(&deps.querier, &info.sender)?; + cfg.authorize(&deps.querier, deps.api, &info.sender)?; // set it to executed prop.status = Status::Executed; @@ -502,37 +504,12 @@ fn list_votes( Ok(VoteListResponse { votes }) } -/// Check if this address is a member and returns its weight. -/// We dont use the group addr's is_member function because it queries using the key as &Addr, not Vec of CannonicalAddr in the latest version -/// The current production group addr on Oraichain is using the v0.13.2 version of CosmWasm, which uses CannonicalAddr -fn is_member( - storage: &dyn Storage, - querier: &QuerierWrapper, - api: &dyn Api, - member: &Addr, - height: Option, -) -> StdResult> { - let cfg = CONFIG.load(storage)?; - let mut old_ver_height = match height { - Some(height) => cfg - .group_addr - .member_at_height(querier, member.to_string(), height.into()), - None => Map::new(MEMBERS_KEY).query( - querier, - cfg.group_addr.addr(), - api.addr_canonicalize(member.as_str())?.to_vec(), - ), - }?; - // if None then we try to query using the new way - if old_ver_height.is_none() { - old_ver_height = Map::new(MEMBERS_KEY).query(querier, cfg.group_addr.addr(), member)?; - } - Ok(old_ver_height) -} - fn query_voter(deps: Deps, voter: String) -> StdResult { let voter_addr = deps.api.addr_validate(&voter)?; - let weight = is_member(deps.storage, &deps.querier, deps.api, &voter_addr, None)?; + let cfg = CONFIG.load(deps.storage)?; + let weight = cfg + .group_addr + .is_member(&deps.querier, deps.api, &voter_addr, None)?; Ok(VoterResponse { weight }) } diff --git a/contracts/cw3-flex-multisig/src/state.rs b/contracts/cw3-flex-multisig/src/state.rs index 14e8ad888..824e52fd9 100644 --- a/contracts/cw3-flex-multisig/src/state.rs +++ b/contracts/cw3-flex-multisig/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, QuerierWrapper}; +use cosmwasm_std::{Addr, Api, QuerierWrapper}; use cw3::{Ballot, DepositInfo, Proposal}; use cw4::Cw4Contract; use cw_storage_plus::{Item, Map}; @@ -34,12 +34,17 @@ impl Config { // - Member: any member of the voting group is authorized // - Only: only passed address is authorized // - None: Everyone are authorized - pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> { + pub fn authorize( + &self, + querier: &QuerierWrapper, + api: &dyn Api, + sender: &Addr, + ) -> Result<(), ContractError> { if let Some(executor) = &self.executor { match executor { Executor::Member => { self.group_addr - .is_member(querier, sender, None)? + .is_member(querier, api, sender, None)? .ok_or(ContractError::Unauthorized {})?; } Executor::Only(addr) => { diff --git a/packages/cw4/src/helpers.rs b/packages/cw4/src/helpers.rs index 57dc4d069..f98c5223d 100644 --- a/packages/cw4/src/helpers.rs +++ b/packages/cw4/src/helpers.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, WasmMsg, - WasmQuery, + to_json_binary, Addr, Api, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, + WasmMsg, WasmQuery, }; use crate::msg::Cw4ExecuteMsg; @@ -30,7 +30,7 @@ impl Cw4Contract { fn encode_msg(&self, msg: Cw4ExecuteMsg) -> StdResult { Ok(WasmMsg::Execute { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, funds: vec![], } .into()) @@ -56,7 +56,7 @@ impl Cw4Contract { fn encode_smart_query(&self, msg: Cw4QueryMsg) -> StdResult> { Ok(WasmQuery::Smart { contract_addr: self.addr().into(), - msg: to_binary(&msg)?, + msg: to_json_binary(&msg)?, } .into()) } @@ -73,17 +73,29 @@ impl Cw4Contract { Item::new(TOTAL_KEY).query(querier, self.addr()) } - /// Check if this address is a member and returns its weight + /// Check if this address is a member and returns its weight. + /// We dont use the group addr's is_member function because it queries using the key as &Addr, not Vec of CannonicalAddr in the latest version + /// The current production group addr on Oraichain is using the v0.13.2 version of CosmWasm, which uses CannonicalAddr pub fn is_member( &self, querier: &QuerierWrapper, + api: &dyn Api, member: &Addr, height: Option, ) -> StdResult> { - match height { + let mut old_ver_height = match height { Some(height) => self.member_at_height(querier, member.to_string(), height.into()), - None => Map::new(MEMBERS_KEY).query(querier, self.addr(), member), + None => Map::new(MEMBERS_KEY).query( + querier, + self.addr(), + api.addr_canonicalize(member.as_str())?.to_vec(), + ), + }?; + // if None then we try to query using the new way + if old_ver_height.is_none() { + old_ver_height = Map::new(MEMBERS_KEY).query(querier, self.addr(), member)?; } + Ok(old_ver_height) } /// Check if this address is a member, and if its weight is >= 1