From 3706c7b01cf8bf6a9a42e5f796a6c5cc3bb3f92a Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Thu, 18 Nov 2021 11:10:42 +0100 Subject: [PATCH] Correct a few assumptions, wasm_execute --- common/mixnet-contract/src/msg.rs | 1 - contracts/mixnet/src/contract.rs | 2 -- contracts/mixnet/src/transactions.rs | 5 ++- contracts/vesting/src/contract.rs | 49 +++++++++------------------- contracts/vesting/src/errors.rs | 2 ++ contracts/vesting/src/messages.rs | 3 -- contracts/vesting/src/vesting.rs | 47 ++++++++++++-------------- 7 files changed, 41 insertions(+), 68 deletions(-) diff --git a/common/mixnet-contract/src/msg.rs b/common/mixnet-contract/src/msg.rs index f8edfd7e08..e89751a61b 100644 --- a/common/mixnet-contract/src/msg.rs +++ b/common/mixnet-contract/src/msg.rs @@ -61,7 +61,6 @@ pub enum ExecuteMsg { DelegateToMixnodeOnBehalf { mix_identity: IdentityKey, delegate_addr: Addr, - coin: Coin, }, UnDelegateFromMixnodeOnBehalf { mix_identity: IdentityKey, diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index 5f52d2a1e4..dc59427d2e 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -146,14 +146,12 @@ pub fn execute( ExecuteMsg::DelegateToMixnodeOnBehalf { mix_identity, delegate_addr, - coin, } => transactions::try_delegate_to_mixnode_on_behalf( deps, env, info, mix_identity, delegate_addr, - coin, ), ExecuteMsg::UnDelegateFromMixnodeOnBehalf { mix_identity, diff --git a/contracts/mixnet/src/transactions.rs b/contracts/mixnet/src/transactions.rs index fdeac6c573..bd3c3ac912 100644 --- a/contracts/mixnet/src/transactions.rs +++ b/contracts/mixnet/src/transactions.rs @@ -670,11 +670,10 @@ pub(crate) fn try_delegate_to_mixnode_on_behalf( info: MessageInfo, mix_identity: IdentityKey, delegate_addr: Addr, - coin: Coin, ) -> Result { // check if the delegation contains any funds of the appropriate denomination - validate_delegation_stake(&[coin.clone()])?; - let amount = coin.amount; + validate_delegation_stake(&info.funds)?; + let amount = info.funds[0].amount; if info.sender != VESTING_CONTRACT_ADDR { return Err(ContractError::Unauthorized); diff --git a/contracts/vesting/src/contract.rs b/contracts/vesting/src/contract.rs index a72e1ae310..b822fe9acf 100644 --- a/contracts/vesting/src/contract.rs +++ b/contracts/vesting/src/contract.rs @@ -4,7 +4,6 @@ use crate::storage::{get_account, get_account_balance, set_account_balance}; use crate::vesting::{ populate_vesting_periods, DelegationAccount, PeriodicVestingAccount, VestingAccount, }; -use config::defaults::DENOM; use cosmwasm_std::{ attr, entry_point, to_binary, BankMsg, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response, Timestamp, Uint128, @@ -41,18 +40,15 @@ pub fn execute( match msg { ExecuteMsg::DelegateToMixnode { mix_identity, - delegate_addr, amount, - } => try_delegate_to_mixnode(mix_identity, delegate_addr, amount, info, env, deps), - ExecuteMsg::UndelegateFromMixnode { - mix_identity, - delegate_addr, - } => try_undelegate_from_mixnode(mix_identity, delegate_addr, info, deps), + } => try_delegate_to_mixnode(mix_identity, amount, info, env, deps), + ExecuteMsg::UndelegateFromMixnode { mix_identity } => { + try_undelegate_from_mixnode(mix_identity, info, deps) + } ExecuteMsg::CreatePeriodicVestingAccount { address, - coin, start_time, - } => try_create_periodic_vesting_account(address, coin, start_time, info, env, deps), + } => try_create_periodic_vesting_account(address, start_time, info, env, deps), ExecuteMsg::WithdrawVestedCoins { amount } => { try_withdraw_vested_coins(amount, env, info, deps) } @@ -86,69 +82,55 @@ fn try_withdraw_vested_coins( let attributes = vec![attr("action", "withdraw")]; - return Ok(Response { + Ok(Response { submessages: Vec::new(), messages, attributes, data: None, - }); + }) } else { - return Err(ContractError::InsufficientSpendable( + Err(ContractError::InsufficientSpendable( address.as_str().to_string(), spendable_coins.amount.u128(), - )); + )) } } else { return Err(ContractError::NoAccountForAddress( address.as_str().to_string(), )); } - Ok(Response::default()) } fn try_delegate_to_mixnode( mix_identity: IdentityKey, - delegate_addr: String, amount: Coin, info: MessageInfo, env: Env, deps: DepsMut, ) -> Result { - if info.sender != ADMIN_ADDRESS { - return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); - } - let address = deps.api.addr_validate(&delegate_addr)?; + let delegate_addr = info.sender; + let address = deps.api.addr_validate(delegate_addr.as_str())?; if let Some(account) = get_account(deps.storage, &address) { - account.try_delegate_to_mixnode( - mix_identity, - amount, - &env, - deps.storage, - Some(deps.querier), - )?; + account.try_delegate_to_mixnode(mix_identity, amount, &env, deps.storage)?; } Ok(Response::default()) } fn try_undelegate_from_mixnode( mix_identity: IdentityKey, - delegate_addr: String, info: MessageInfo, deps: DepsMut, ) -> Result { - if info.sender != ADMIN_ADDRESS { - return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); - } - let address = deps.api.addr_validate(&delegate_addr)?; + let delegate_addr = info.sender; + let address = deps.api.addr_validate(delegate_addr.as_str())?; if let Some(account) = get_account(deps.storage, &address) { - account.try_undelegate_from_mixnode(mix_identity, deps.storage, Some(deps.querier))?; + account.try_undelegate_from_mixnode(mix_identity, deps.storage)?; } Ok(Response::default()) } fn try_create_periodic_vesting_account( address: String, - coin: Coin, start_time: Option, info: MessageInfo, env: Env, @@ -157,6 +139,7 @@ fn try_create_periodic_vesting_account( if info.sender != ADMIN_ADDRESS { return Err(ContractError::NotAdmin(info.sender.as_str().to_string())); } + let coin = info.funds[0].clone(); let address = deps.api.addr_validate(&address)?; let start_time = start_time.unwrap_or_else(|| env.block.time.seconds()); let periods = populate_vesting_periods(start_time, NUM_VESTING_PERIODS); diff --git a/contracts/vesting/src/errors.rs b/contracts/vesting/src/errors.rs index cc1ef8708e..3c7e1904df 100644 --- a/contracts/vesting/src/errors.rs +++ b/contracts/vesting/src/errors.rs @@ -15,4 +15,6 @@ pub enum ContractError { InsufficientBalance(String, u128), #[error("Insufficient spendable balance")] InsufficientSpendable(String, u128), + #[error("Only delegation owner can perform delegation actions, {0} is not the delegation owner")] + NotDelegate(String), } diff --git a/contracts/vesting/src/messages.rs b/contracts/vesting/src/messages.rs index 676464a7c8..ad5303df1a 100644 --- a/contracts/vesting/src/messages.rs +++ b/contracts/vesting/src/messages.rs @@ -12,16 +12,13 @@ pub struct InitMsg {} pub enum ExecuteMsg { DelegateToMixnode { mix_identity: IdentityKey, - delegate_addr: String, amount: Coin, }, UndelegateFromMixnode { mix_identity: IdentityKey, - delegate_addr: String, }, CreatePeriodicVestingAccount { address: String, - coin: Coin, start_time: Option, }, WithdrawVestedCoins { diff --git a/contracts/vesting/src/vesting.rs b/contracts/vesting/src/vesting.rs index 4f2f770922..0d423d0529 100644 --- a/contracts/vesting/src/vesting.rs +++ b/contracts/vesting/src/vesting.rs @@ -5,12 +5,11 @@ use crate::storage::{ set_account_delegations, }; use config::defaults::{DEFAULT_MIXNET_CONTRACT_ADDRESS, DENOM}; -use cosmwasm_std::{Addr, Coin, DepsMut, Env, QuerierWrapper, Storage, Timestamp, Uint128}; +use cosmwasm_std::{wasm_execute, Addr, Coin, Env, QuerierWrapper, Storage, Timestamp, Uint128}; use mixnet_contract::ExecuteMsg as MixnetExecuteMsg; use mixnet_contract::IdentityKey; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; pub trait VestingAccount { // locked_coins returns the set of coins that are not spendable (can still be delegated tough) (i.e. locked), @@ -58,16 +57,12 @@ pub trait DelegationAccount { amount: Coin, env: &Env, storage: &mut dyn Storage, - // There isn't a trait that unifies Queriers so we clutch by passing in the option here, so we'll query - // mixnet contract only when we're deployed, during testing query will not be sent. - querier: Option, ) -> Result<(), ContractError>; fn try_undelegate_from_mixnode( &self, mix_identity: IdentityKey, storage: &mut dyn Storage, - querier: Option, ) -> Result<(), ContractError>; // track_delegation performs internal vesting accounting necessary when @@ -224,18 +219,15 @@ impl DelegationAccount for PeriodicVestingAccount { coin: Coin, env: &Env, storage: &mut dyn Storage, - querier: Option, ) -> Result<(), ContractError> { if coin.amount < self.get_balance(storage) { - if let Some(querier) = querier { - let msg = MixnetExecuteMsg::DelegateToMixnodeOnBehalf { - mix_identity: mix_identity.clone(), - delegate_addr: self.address.clone(), - coin: coin.clone(), - }; - querier.query_wasm_smart(DEFAULT_MIXNET_CONTRACT_ADDRESS, &msg)?; - } + let msg = MixnetExecuteMsg::DelegateToMixnodeOnBehalf { + mix_identity: mix_identity.clone(), + delegate_addr: self.address.clone(), + }; + wasm_execute(DEFAULT_MIXNET_CONTRACT_ADDRESS, &msg, vec![coin.clone()])?; self.track_delegation(env.block.time, mix_identity, coin, storage)?; + Ok(()) } else { return Err(ContractError::InsufficientBalance( @@ -249,15 +241,19 @@ impl DelegationAccount for PeriodicVestingAccount { &self, mix_identity: IdentityKey, storage: &mut dyn Storage, - querier: Option, ) -> Result<(), ContractError> { - if let Some(querier) = querier { - let msg = MixnetExecuteMsg::UnDelegateFromMixnodeOnBehalf { - mix_identity: mix_identity.clone(), - delegate_addr: self.address.clone(), - }; - querier.query_wasm_smart(DEFAULT_MIXNET_CONTRACT_ADDRESS, &msg)?; - } + let msg = MixnetExecuteMsg::UnDelegateFromMixnodeOnBehalf { + mix_identity: mix_identity.clone(), + delegate_addr: self.address.clone(), + }; + wasm_execute( + DEFAULT_MIXNET_CONTRACT_ADDRESS, + &msg, + vec![Coin { + amount: Uint128(0), + denom: DENOM.to_string(), + }], + )?; self.track_undelegation(mix_identity, storage)?; Ok(()) } @@ -280,6 +276,7 @@ impl DelegationAccount for PeriodicVestingAccount { amount: delegation_amount.amount, block_time, }); + // TODO: track balance here as well. set_account_delegations(storage, &self.address, delegations)?; Ok(()) } @@ -296,7 +293,7 @@ impl DelegationAccount for PeriodicVestingAccount { .filter(|d| d.mix_identity != mix_identity) .collect(); // Since we're always removing the entire delegation we can just drop the key - + // TODO: track balance here as well. Ok(set_account_delegations( storage, &self.address, @@ -530,7 +527,6 @@ mod tests { }, &env, &mut deps.storage, - None, ); assert!(err.is_err()); @@ -542,7 +538,6 @@ mod tests { }, &env, &mut deps.storage, - None, ); assert!(ok.is_ok());