diff --git a/gears/src/x/errors.rs b/gears/src/x/errors.rs index 6db37a44..b5547bb1 100644 --- a/gears/src/x/errors.rs +++ b/gears/src/x/errors.rs @@ -178,6 +178,8 @@ pub enum BankKeeperError { AccountPermission, #[error("{0} is not allowed to receive funds. Probably tried send to module as account")] Blocked(AccAddress), + #[error("Send disabled for denom: {0}")] + SendDisabled(Denom), #[error("{0}")] GasError(#[from] GasStoreErrors), } diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 09e68db2..c639a617 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -269,6 +269,10 @@ impl< amount, }: MsgSend, ) -> Result<(), BankKeeperError> { + if let Some(denom) = self.is_send_enabled_for(ctx, amount.inner())? { + Err(BankKeeperError::SendDisabled(denom.clone()))? + } + let mut events = vec![]; for send_coin in amount.inner() { @@ -669,6 +673,34 @@ impl< Err(_) => Ok((None, total, pagination)), } } + + fn is_send_enabled_for<'a, DB: Database, CTX: QueryableContext>( + &self, + ctx: &CTX, + coins: impl IntoIterator, + ) -> Result, GasStoreErrors> { + let BankParams { + send_enabled, + default_send_enabled, + } = self.bank_params_keeper.try_get(ctx)?; + + let send_enabled = send_enabled + .into_iter() + .map(|this| (this.denom, this.enabled)) + .collect::>(); + for UnsignedCoin { denom, amount: _ } in coins { + let enabled = send_enabled + .get(denom) + .map(bool::clone) + .unwrap_or(default_send_enabled); + + if !enabled { + return Ok(Some(denom)); + } + } + + Ok(None) + } } //TODO: copy tests across diff --git a/x/bank/src/params/mod.rs b/x/bank/src/params/mod.rs index 7188e0e7..5a13519e 100644 --- a/x/bank/src/params/mod.rs +++ b/x/bank/src/params/mod.rs @@ -1,12 +1,8 @@ use gears::application::keepers::params::ParamsKeeper; -use gears::context::{InfallibleContext, QueryableContext}; use gears::derive::Protobuf; use gears::extensions::corruption::UnwrapCorrupt; use gears::params::{ParamKind, ParamsDeserialize, ParamsSerialize, ParamsSubspaceKey}; -use gears::store::database::Database; -use gears::store::StoreKey; use gears::types::denom::Denom; -use gears::types::store::gas::errors::GasStoreErrors; use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; @@ -94,37 +90,6 @@ pub struct BankParamsKeeper { pub params_subspace_key: PSK, } -impl BankParamsKeeper { - pub fn send_enabled>( - &self, - ctx: &CTX, - denom: &Denom, - ) -> Option { - self.get(ctx) - .send_enabled - .into_iter() - .find_map(|this| match denom == &this.denom { - true => Some(this.enabled), - false => None, - }) - } - - pub fn try_send_enabled>( - &self, - ctx: &CTX, - denom: &Denom, - ) -> Result, GasStoreErrors> { - Ok(self - .try_get(ctx)? - .send_enabled - .into_iter() - .find_map(|this| match denom == &this.denom { - true => Some(this.enabled), - false => None, - })) - } -} - impl ParamsKeeper for BankParamsKeeper { type Param = BankParams;