terra/token_bridge: allow newer sequenced vaa metadata

Change-Id: Ie81584abe6671595118082796df57bcea75a8fd3
This commit is contained in:
Reisen 2021-10-08 14:44:28 +00:00 committed by David Paryente
parent e2a16b6756
commit 91087bdb66
2 changed files with 37 additions and 12 deletions

View File

@ -41,6 +41,8 @@ use crate::{
wrapped_asset_address, wrapped_asset_address,
wrapped_asset_address_read, wrapped_asset_address_read,
wrapped_asset_read, wrapped_asset_read,
wrapped_asset_seq,
wrapped_asset_seq_read,
Action, Action,
AssetMeta, AssetMeta,
ConfigInfo, ConfigInfo,
@ -273,6 +275,7 @@ fn handle_attest_meta(
env: Env, env: Env,
emitter_chain: u16, emitter_chain: u16,
emitter_address: Vec<u8>, emitter_address: Vec<u8>,
sequence: u64,
data: &Vec<u8>, data: &Vec<u8>,
) -> StdResult<Response> { ) -> StdResult<Response> {
let meta = AssetMeta::deserialize(data)?; let meta = AssetMeta::deserialize(data)?;
@ -294,16 +297,26 @@ fn handle_attest_meta(
let cfg = config_read(deps.storage).load()?; let cfg = config_read(deps.storage).load()?;
let asset_id = build_asset_id(meta.token_chain, &meta.token_address.as_slice()); let asset_id = build_asset_id(meta.token_chain, &meta.token_address.as_slice());
if wrapped_asset_read(deps.storage).load(&asset_id).is_ok() { // If a CW20 wrapped already exists and this message has a newer sequence ID
return Err(StdError::generic_err( // we allow updating the metadata. If not, we create a brand new token.
"this asset has already been attested", let message = if let Ok(contract) = wrapped_asset_read(deps.storage).load(&asset_id) {
)); // Prevent anyone from re-attesting with old VAAs.
} if sequence <= wrapped_asset_seq_read(deps.storage).load(&asset_id)? {
return Err(StdError::generic_err(
wrapped_asset(deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?; "this asset has already been attested",
));
Ok( }
Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract,
msg: to_binary(&WrappedMsg::UpdateMetadata {
name: get_string_from_32(&meta.name)?,
symbol: get_string_from_32(&meta.symbol)?,
})?,
funds: vec![],
})
} else {
wrapped_asset(deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?;
CosmosMsg::Wasm(WasmMsg::Instantiate {
admin: Some(env.contract.address.to_string()), admin: Some(env.contract.address.to_string()),
code_id: cfg.wrapped_asset_code_id, code_id: cfg.wrapped_asset_code_id,
msg: to_binary(&WrappedInit { msg: to_binary(&WrappedInit {
@ -322,8 +335,10 @@ fn handle_attest_meta(
})?, })?,
funds: vec![], funds: vec![],
label: String::new(), label: String::new(),
})), })
) };
wrapped_asset_seq(deps.storage).save(&asset_id, &sequence)?;
Ok(Response::new().add_message(message))
} }
fn handle_create_asset_meta( fn handle_create_asset_meta(
@ -465,6 +480,7 @@ fn submit_vaa(
env, env,
vaa.emitter_chain, vaa.emitter_chain,
vaa.emitter_address, vaa.emitter_address,
vaa.sequence,
&message.payload, &message.payload,
), ),
_ => ContractError::InvalidVAAAction.std_err(), _ => ContractError::InvalidVAAAction.std_err(),

View File

@ -28,6 +28,7 @@ type HumanAddr = String;
pub static CONFIG_KEY: &[u8] = b"config"; pub static CONFIG_KEY: &[u8] = b"config";
pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset"; pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset";
pub static WRAPPED_ASSET_SEQ_KEY: &[u8] = b"wrapped_seq_asset";
pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address"; pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address";
pub static BRIDGE_CONTRACTS: &[u8] = b"bridge_contracts"; pub static BRIDGE_CONTRACTS: &[u8] = b"bridge_contracts";
pub static BRIDGE_DEPOSITS: &[u8] = b"bridge_deposits"; pub static BRIDGE_DEPOSITS: &[u8] = b"bridge_deposits";
@ -76,6 +77,14 @@ pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<HumanAddr> {
bucket_read(storage, WRAPPED_ASSET_KEY) bucket_read(storage, WRAPPED_ASSET_KEY)
} }
pub fn wrapped_asset_seq(storage: &mut dyn Storage) -> Bucket<u64> {
bucket(storage, WRAPPED_ASSET_SEQ_KEY)
}
pub fn wrapped_asset_seq_read(storage: &mut dyn Storage) -> ReadonlyBucket<u64> {
bucket_read(storage, WRAPPED_ASSET_SEQ_KEY)
}
pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> { pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
bucket(storage, WRAPPED_ASSET_ADDRESS_KEY) bucket(storage, WRAPPED_ASSET_ADDRESS_KEY)
} }