diff --git a/cosmwasm/contracts/crosschain-registry/src/error.rs b/cosmwasm/contracts/crosschain-registry/src/error.rs index 87a8697b75d..210158657fa 100644 --- a/cosmwasm/contracts/crosschain-registry/src/error.rs +++ b/cosmwasm/contracts/crosschain-registry/src/error.rs @@ -36,6 +36,11 @@ pub enum ContractError { #[error("contract alias already exists: {alias:?}")] AliasAlreadyExists { alias: String }, + #[error( + "PFM validation already in progress for {chain:?}. Wait for the ibc lifecycle to complete" + )] + PFMValidationAlreadyInProgress { chain: String }, + #[error("authorized address already exists for source chain: {source_chain:?}")] ChainAuthorizedAddressAlreadyExists { source_chain: String }, diff --git a/cosmwasm/contracts/crosschain-registry/src/execute.rs b/cosmwasm/contracts/crosschain-registry/src/execute.rs index 89523e2bb9c..c1e9b7d6ccd 100644 --- a/cosmwasm/contracts/crosschain-registry/src/execute.rs +++ b/cosmwasm/contracts/crosschain-registry/src/execute.rs @@ -48,9 +48,22 @@ pub fn propose_pfm( ) -> Result { let (deps, env, info) = ctx; + // enforce lowercase let chain = chain.to_lowercase(); - // Store the chain to validate. If validation fails this will be reverted + // validation + let registry = Registry::default(deps.as_ref()); + let coin = cw_utils::one_coin(&info)?; + let native_chain = registry.get_native_chain(&coin.denom)?; + + if native_chain.as_ref() != chain { + return Err(ContractError::CoinFronInvalidChain { + supplied_chain: native_chain.as_ref().to_string(), + expected_chain: chain, + }); + } + + // check if the chain is already registered or is in progress if let Some(chain_pfm) = CHAIN_PFM_MAP.may_load(deps.storage, &chain)? { if chain_pfm.is_validated() { // Only authorized addresses can ask for a validated PFM to be re-checked @@ -59,25 +72,20 @@ pub fn propose_pfm( let user_permission = check_is_authorized(deps.as_ref(), info.sender.clone(), Some(chain.clone()))?; check_action_permission(FullOperation::Change, user_permission)?; + } else { + return Err(ContractError::PFMValidationAlreadyInProgress { + chain: chain.clone(), + }); } }; + // Store the chain to validate CHAIN_PFM_MAP.save(deps.storage, &chain, &ChainPFM::default())?; - let registry = Registry::default(deps.as_ref()); - - let coin = cw_utils::one_coin(&info)?; - let native_chain = registry.get_native_chain(&coin.denom)?; - - if native_chain.as_ref() != chain { - return Err(ContractError::CoinFronInvalidChain { - supplied_chain: native_chain.as_ref().to_string(), - expected_chain: chain, - }); - } - let own_addr = env.contract.address; + // redeclaring (shadowing) registry to avoid issues with the borrow checker + let registry = Registry::default(deps.as_ref()); let ibc_transfer = registry.unwrap_coin_into( coin, own_addr.to_string(),