diff --git a/terra/contracts-5/token-bridge/Cargo.toml b/terra/contracts-5/token-bridge/Cargo.toml index a0df81ec..7465bd1d 100644 --- a/terra/contracts-5/token-bridge/Cargo.toml +++ b/terra/contracts-5/token-bridge/Cargo.toml @@ -14,18 +14,17 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-std = { version = "0.10.0" } -cosmwasm-storage = { version = "0.10.0" } -schemars = "0.7" +cosmwasm-std = { version = "0.16.0" } +cosmwasm-storage = { version = "0.16.0" } +schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw20 = "0.2.2" -cw20-base = { version = "0.2.2", features = ["library"] } +cw20 = "0.8.0" +cw20-base = { version = "0.8.0", features = ["library"] } cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] } -terraswap = "1.1.0" +terraswap = "2.4.0" wormhole = { path = "../wormhole", features = ["library"] } - thiserror = { version = "1.0.20" } -k256 = { version = "0.5.9", default-features = false, features = ["ecdsa"] } +k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } sha3 = { version = "0.9.1", default-features = false } generic-array = { version = "0.14.4" } hex = "0.4.2" @@ -33,5 +32,5 @@ lazy_static = "1.4.0" bigint = "4" [dev-dependencies] -cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] } -serde_json = "1.0" \ No newline at end of file +cosmwasm-vm = { version = "0.16.0", default-features = false } +serde_json = "1.0" diff --git a/terra/contracts-5/token-bridge/src/contract.rs b/terra/contracts-5/token-bridge/src/contract.rs index de3f7b15..d682ec3d 100644 --- a/terra/contracts-5/token-bridge/src/contract.rs +++ b/terra/contracts-5/token-bridge/src/contract.rs @@ -1,22 +1,20 @@ use crate::msg::WrappedRegistryResponse; use cosmwasm_std::{ - log, + entry_point, to_binary, - Api, Binary, CanonicalAddr, Coin, CosmosMsg, + Deps, + DepsMut, + Empty, Env, - Extern, - HandleResponse, - HumanAddr, - InitResponse, - Querier, + MessageInfo, QueryRequest, + Response, StdError, StdResult, - Storage, Uint128, WasmMsg, WasmQuery, @@ -24,8 +22,8 @@ use cosmwasm_std::{ use crate::{ msg::{ - HandleMsg, - InitMsg, + ExecuteMsg, + InstantiateMsg, QueryMsg, }, state::{ @@ -58,12 +56,12 @@ use wormhole::{ }; use cw20_base::msg::{ - HandleMsg as TokenMsg, + ExecuteMsg as TokenMsg, QueryMsg as TokenQuery, }; use wormhole::msg::{ - HandleMsg as WormholeHandleMsg, + ExecuteMsg as WormholeExecuteMsg, QueryMsg as WormholeQueryMsg, }; @@ -77,9 +75,9 @@ use wormhole::state::{ use cw20::TokenInfoResponse; use cw20_wrapped::msg::{ - HandleMsg as WrappedMsg, + ExecuteMsg as WrappedMsg, InitHook, - InitMsg as WrappedInit, + InstantiateMsg as WrappedInit, QueryMsg as WrappedQuery, WrappedAssetInfoResponse, }; @@ -97,16 +95,20 @@ use std::cmp::{ min, }; +type HumanAddr = String; + // Chain ID of Terra const CHAIN_ID: u16 = 3; const WRAPPED_ASSET_UPDATING: &str = "updating"; -pub fn init( - deps: &mut Extern, +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, _env: Env, - msg: InitMsg, -) -> StdResult { + _info: MessageInfo, + msg: InstantiateMsg, +) -> StdResult { // Save general wormhole info let state = ConfigInfo { gov_chain: msg.gov_chain, @@ -114,15 +116,12 @@ pub fn init( wormhole_contract: msg.wormhole_contract, wrapped_asset_code_id: msg.wrapped_asset_code_id, }; - config(&mut deps.storage).save(&state)?; + config(deps.storage).save(&state)?; - Ok(InitResponse::default()) + Ok(Response::default()) } -pub fn coins_after_tax( - deps: &mut Extern, - coins: Vec, -) -> StdResult> { +pub fn coins_after_tax(deps: DepsMut, coins: Vec) -> StdResult> { let mut res = vec![]; for coin in coins { let asset = Asset { @@ -131,17 +130,13 @@ pub fn coins_after_tax( denom: coin.denom.clone(), }, }; - res.push(asset.deduct_tax(&deps)?); + res.push(asset.deduct_tax(&deps.querier)?); } Ok(res) } -pub fn parse_vaa( - deps: &mut Extern, - block_time: u64, - data: &Binary, -) -> StdResult { - let cfg = config_read(&deps.storage).load()?; +pub fn parse_vaa(deps: DepsMut, block_time: u64, data: &Binary) -> StdResult { + let cfg = config_read(deps.storage).load()?; let vaa: ParsedVAA = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: cfg.wormhole_contract.clone(), msg: to_binary(&WormholeQueryMsg::VerifyVAA { @@ -152,16 +147,13 @@ pub fn parse_vaa( Ok(vaa) } -pub fn handle( - deps: &mut Extern, - env: Env, - msg: HandleMsg, -) -> StdResult { +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { - HandleMsg::RegisterAssetHook { asset_id } => { - handle_register_asset(deps, env, &asset_id.as_slice()) + ExecuteMsg::RegisterAssetHook { asset_id } => { + handle_register_asset(deps, env, info, &asset_id.as_slice()) } - HandleMsg::InitiateTransfer { + ExecuteMsg::InitiateTransfer { asset, amount, recipient_chain, @@ -171,6 +163,7 @@ pub fn handle( } => handle_initiate_transfer( deps, env, + info, asset, amount, recipient_chain, @@ -178,59 +171,54 @@ pub fn handle( fee, nonce, ), - HandleMsg::SubmitVaa { data } => submit_vaa(deps, env, &data), - HandleMsg::CreateAssetMeta { + ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data), + ExecuteMsg::CreateAssetMeta { asset_address, nonce, - } => handle_create_asset_meta(deps, env, &asset_address, nonce), + } => handle_create_asset_meta(deps, env, info, &asset_address, nonce), } } /// Handle wrapped asset registration messages -fn handle_register_asset( - deps: &mut Extern, - env: Env, +fn handle_register_asset( + deps: DepsMut, + _env: Env, + info: MessageInfo, asset_id: &[u8], -) -> StdResult { - let mut bucket = wrapped_asset(&mut deps.storage); +) -> StdResult { + let mut bucket = wrapped_asset(deps.storage); let result = bucket.load(asset_id); let result = result.map_err(|_| ContractError::RegistrationForbidden.std())?; if result != HumanAddr::from(WRAPPED_ASSET_UPDATING) { return ContractError::AssetAlreadyRegistered.std_err(); } - bucket.save(asset_id, &env.message.sender)?; + bucket.save(asset_id, &info.sender.to_string())?; - let contract_address: CanonicalAddr = deps.api.canonical_address(&env.message.sender)?; - wrapped_asset_address(&mut deps.storage) - .save(contract_address.as_slice(), &asset_id.to_vec())?; + let contract_address: CanonicalAddr = deps.api.addr_canonicalize(&info.sender.as_str())?; + wrapped_asset_address(deps.storage).save(contract_address.as_slice(), &asset_id.to_vec())?; - Ok(HandleResponse { - messages: vec![], - log: vec![ - log("action", "register_asset"), - log("asset_id", format!("{:?}", asset_id)), - log("contract_addr", env.message.sender), - ], - data: None, - }) + Ok(Response::new() + .add_attribute("action", "register_asset") + .add_attribute("asset_id", format!("{:?}", asset_id)) + .add_attribute("contract_addr", info.sender)) } -fn handle_attest_meta( - deps: &mut Extern, +fn handle_attest_meta( + deps: DepsMut, env: Env, emitter_chain: u16, emitter_address: Vec, data: &Vec, -) -> StdResult { +) -> StdResult { let meta = AssetMeta::deserialize(data)?; let expected_contract = - bridge_contracts_read(&deps.storage).load(&emitter_chain.to_be_bytes())?; + bridge_contracts_read(deps.storage).load(&emitter_chain.to_be_bytes())?; // must be sent by a registered token bridge contract if expected_contract != emitter_address { - return Err(StdError::unauthorized()); + return Err(StdError::generic_err("invalid emitter")); } if CHAIN_ID == meta.token_chain { @@ -239,22 +227,20 @@ 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()); - if wrapped_asset_read(&mut deps.storage) - .load(&asset_id) - .is_ok() - { + if wrapped_asset_read(deps.storage).load(&asset_id).is_ok() { return Err(StdError::generic_err( "this asset has already been attested", )); } - wrapped_asset(&mut deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?; + wrapped_asset(deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?; - Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + admin: None, code_id: cfg.wrapped_asset_code_id, msg: to_binary(&WrappedInit { name: get_string_from_32(&meta.name)?, @@ -264,34 +250,33 @@ fn handle_attest_meta( decimals: min(meta.decimals, 8u8), mint: None, init_hook: Some(InitHook { - contract_addr: env.contract.address, - msg: to_binary(&HandleMsg::RegisterAssetHook { + contract_addr: env.contract.address.to_string(), + msg: to_binary(&ExecuteMsg::RegisterAssetHook { asset_id: asset_id.to_vec().into(), })?, }), })?, - send: vec![], - label: None, - })], - log: vec![], - data: None, - }) + funds: vec![], + label: String::new(), + })), + ) } -fn handle_create_asset_meta( - deps: &mut Extern, +fn handle_create_asset_meta( + deps: DepsMut, env: Env, + info: MessageInfo, asset_address: &HumanAddr, nonce: u32, -) -> StdResult { - let cfg = config_read(&deps.storage).load()?; +) -> StdResult { + let cfg = config_read(deps.storage).load()?; let request = QueryRequest::Wasm(WasmQuery::Smart { contract_addr: asset_address.clone(), msg: to_binary(&TokenQuery::TokenInfo {})?, }); - let asset_canonical = deps.api.canonical_address(asset_address)?; + let asset_canonical = deps.api.addr_canonicalize(asset_address)?; let token_info: TokenInfoResponse = deps.querier.query(&request)?; let meta: AssetMeta = AssetMeta { @@ -307,40 +292,37 @@ fn handle_create_asset_meta( payload: meta.serialize().to_vec(), }; - Ok(HandleResponse { - messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + Ok(Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cfg.wormhole_contract, - msg: to_binary(&WormholeHandleMsg::PostMessage { + msg: to_binary(&WormholeExecuteMsg::PostMessage { message: Binary::from(token_bridge_message.serialize()), nonce, })?, // forward coins sent to this message - send: coins_after_tax(deps, env.message.sent_funds.clone())?, - })], - log: vec![ - log("meta.token_chain", CHAIN_ID), - log("meta.token", asset_address), - log("meta.nonce", nonce), - log("meta.block_time", env.block.time), - ], - data: None, - }) + funds: coins_after_tax(deps, info.funds.clone())?, + })) + .add_attribute("meta.token_chain", CHAIN_ID.to_string()) + .add_attribute("meta.token", asset_address) + .add_attribute("meta.nonce", nonce.to_string()) + .add_attribute("meta.block_time", env.block.time.seconds().to_string())) } -fn submit_vaa( - deps: &mut Extern, +fn submit_vaa( + mut deps: DepsMut, env: Env, + info: MessageInfo, data: &Binary, -) -> StdResult { - let state = config_read(&deps.storage).load()?; +) -> StdResult { + let state = config_read(deps.storage).load()?; - let vaa = parse_vaa(deps, env.block.time, data)?; + let vaa = parse_vaa(deps.branch(), env.block.time.seconds(), data)?; let data = vaa.payload; - if vaa_archive_check(&deps.storage, vaa.hash.as_slice()) { + if vaa_archive_check(deps.storage, vaa.hash.as_slice()) { return ContractError::VaaAlreadyExecuted.std_err(); } - vaa_archive_add(&mut deps.storage, vaa.hash.as_slice())?; + vaa_archive_add(deps.storage, vaa.hash.as_slice())?; // check if vaa is from governance if state.gov_chain == vaa.emitter_chain && state.gov_address == vaa.emitter_address { @@ -349,10 +331,11 @@ fn submit_vaa( let message = TokenBridgeMessage::deserialize(&data)?; - let result = match message.action { + match message.action { Action::TRANSFER => handle_complete_transfer( deps, env, + info, vaa.emitter_chain, vaa.emitter_address, &message.payload, @@ -365,15 +348,10 @@ fn submit_vaa( &message.payload, ), _ => ContractError::InvalidVAAAction.std_err(), - }; - return result; + } } -fn handle_governance_payload( - deps: &mut Extern, - env: Env, - data: &Vec, -) -> StdResult { +fn handle_governance_payload(deps: DepsMut, env: Env, data: &Vec) -> StdResult { let gov_packet = GovernancePacket::deserialize(&data)?; let module = get_string_from_32(&gov_packet.module)?; @@ -393,51 +371,43 @@ fn handle_governance_payload( } } -fn handle_register_chain( - deps: &mut Extern, - env: Env, - data: &Vec, -) -> StdResult { +fn handle_register_chain(deps: DepsMut, _env: Env, data: &Vec) -> StdResult { let RegisterChain { chain_id, chain_address, } = RegisterChain::deserialize(&data)?; - let existing = bridge_contracts_read(&deps.storage).load(&chain_id.to_be_bytes()); + let existing = bridge_contracts_read(deps.storage).load(&chain_id.to_be_bytes()); if existing.is_ok() { return Err(StdError::generic_err( "bridge contract already exists for this chain", )); } - let mut bucket = bridge_contracts(&mut deps.storage); + let mut bucket = bridge_contracts(deps.storage); bucket.save(&chain_id.to_be_bytes(), &chain_address)?; - Ok(HandleResponse { - messages: vec![], - log: vec![ - log("chain_id", chain_id), - log("chain_address", hex::encode(chain_address)), - ], - data: None, - }) + Ok(Response::new() + .add_attribute("chain_id", chain_id.to_string()) + .add_attribute("chain_address", hex::encode(chain_address))) } -fn handle_complete_transfer( - deps: &mut Extern, - env: Env, +fn handle_complete_transfer( + deps: DepsMut, + _env: Env, + info: MessageInfo, emitter_chain: u16, emitter_address: Vec, data: &Vec, -) -> StdResult { +) -> StdResult { let transfer_info = TransferInfo::deserialize(&data)?; let expected_contract = - bridge_contracts_read(&deps.storage).load(&emitter_chain.to_be_bytes())?; + bridge_contracts_read(deps.storage).load(&emitter_chain.to_be_bytes())?; // must be sent by a registered token bridge contract if expected_contract != emitter_address { - return Err(StdError::unauthorized()); + return Err(StdError::generic_err("invalid emitter")); } if transfer_info.recipient_chain != CHAIN_ID { @@ -464,62 +434,58 @@ fn handle_complete_transfer( let asset_id = build_asset_id(token_chain, &asset_address); // Check if this asset is already deployed - let contract_addr = wrapped_asset_read(&deps.storage).load(&asset_id).ok(); + let contract_addr = wrapped_asset_read(deps.storage).load(&asset_id).ok(); return if let Some(contract_addr) = contract_addr { // Asset already deployed, just mint let recipient = deps .api - .human_address(&target_address) + .addr_humanize(&target_address) .or_else(|_| ContractError::WrongTargetAddressFormat.std_err())?; let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.clone(), msg: to_binary(&WrappedMsg::Mint { - recipient: recipient.clone(), + recipient: recipient.to_string(), amount: Uint128::from(amount), })?, - send: vec![], + funds: vec![], })]; if fee != 0 { messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.clone(), msg: to_binary(&WrappedMsg::Mint { - recipient: env.message.sender.clone(), + recipient: info.sender.to_string(), amount: Uint128::from(fee), })?, - send: vec![], + funds: vec![], })) } - Ok(HandleResponse { - messages, - log: vec![ - log("action", "complete_transfer_wrapped"), - log("contract", contract_addr), - log("recipient", recipient), - log("amount", amount), - ], - data: None, - }) + Ok(Response::new() + .add_messages(messages) + .add_attribute("action", "complete_transfer_wrapped") + .add_attribute("contract", contract_addr) + .add_attribute("recipient", recipient) + .add_attribute("amount", amount.to_string())) } else { Err(StdError::generic_err("Wrapped asset not deployed. To deploy, invoke CreateWrapped with the associated AssetMeta")) }; } else { let token_address = transfer_info.token_address.as_slice().get_address(0); - let recipient = deps.api.human_address(&target_address)?; - let contract_addr = deps.api.human_address(&token_address)?; + let recipient = deps.api.addr_humanize(&target_address)?; + let contract_addr = deps.api.addr_humanize(&token_address)?; // note -- here the amount is the amount the recipient will receive; // amount + fee is the total sent - receive_native(&mut deps.storage, &token_address, Uint128(amount + fee))?; + receive_native(deps.storage, &token_address, Uint128::new(amount + fee))?; // undo normalization to 8 decimals let token_info: TokenInfoResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: contract_addr.clone(), + contract_addr: contract_addr.to_string(), msg: to_binary(&TokenQuery::TokenInfo {})?, }))?; @@ -529,48 +495,45 @@ fn handle_complete_transfer( fee = fee.checked_mul(multiplier).unwrap(); let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), + contract_addr: contract_addr.to_string(), msg: to_binary(&TokenMsg::Transfer { - recipient: recipient.clone(), + recipient: recipient.to_string(), amount: Uint128::from(amount), })?, - send: vec![], + funds: vec![], })]; if fee != 0 { messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), + contract_addr: contract_addr.to_string(), msg: to_binary(&TokenMsg::Transfer { - recipient: env.message.sender.clone(), + recipient: info.sender.to_string(), amount: Uint128::from(fee), })?, - send: vec![], + funds: vec![], })) } - Ok(HandleResponse { - messages, - log: vec![ - log("action", "complete_transfer_native"), - log("recipient", recipient), - log("contract", contract_addr), - log("amount", amount), - ], - data: None, - }) + Ok(Response::new() + .add_messages(messages) + .add_attribute("action", "complete_transfer_native") + .add_attribute("recipient", recipient) + .add_attribute("contract", contract_addr) + .add_attribute("amount", amount.to_string())) } } -fn handle_initiate_transfer( - deps: &mut Extern, +fn handle_initiate_transfer( + mut deps: DepsMut, env: Env, + info: MessageInfo, asset: HumanAddr, mut amount: Uint128, recipient_chain: u16, recipient: Vec, mut fee: Uint128, nonce: u32, -) -> StdResult { +) -> StdResult { if recipient_chain == CHAIN_ID { return ContractError::SameSourceAndTarget.std_err(); } @@ -586,23 +549,23 @@ fn handle_initiate_transfer( let asset_chain: u16; let asset_address: Vec; - let cfg: ConfigInfo = config_read(&deps.storage).load()?; - let asset_canonical: CanonicalAddr = deps.api.canonical_address(&asset)?; + let cfg: ConfigInfo = config_read(deps.storage).load()?; + let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?; let mut messages: Vec = vec![]; - match wrapped_asset_address_read(&deps.storage).load(asset_canonical.as_slice()) { + match wrapped_asset_address_read(deps.storage).load(asset_canonical.as_slice()) { Ok(_) => { // This is a deployed wrapped asset, burn it messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: asset.clone(), msg: to_binary(&WrappedMsg::Burn { - account: env.message.sender.clone(), + account: info.sender.to_string(), amount, })?, - send: vec![], + funds: vec![], })); - let request = QueryRequest::<()>::Wasm(WasmQuery::Smart { + let request = QueryRequest::::Wasm(WasmQuery::Smart { contract_addr: asset, msg: to_binary(&WrappedQuery::WrappedAssetInfo {})?, }); @@ -622,13 +585,13 @@ fn handle_initiate_transfer( let decimals = token_info.decimals; let multiplier = 10u128.pow((max(decimals, 8u8) - 8u8) as u32); // chop off dust - amount = Uint128( + amount = Uint128::new( amount .u128() .checked_sub(amount.u128().checked_rem(multiplier).unwrap()) .unwrap(), ); - fee = Uint128( + fee = Uint128::new( fee.u128() .checked_sub(fee.u128().checked_rem(multiplier).unwrap()) .unwrap(), @@ -638,20 +601,20 @@ fn handle_initiate_transfer( messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: asset, msg: to_binary(&TokenMsg::TransferFrom { - owner: env.message.sender.clone(), - recipient: env.contract.address.clone(), + owner: info.sender.to_string(), + recipient: env.contract.address.to_string(), amount, })?, - send: vec![], + funds: vec![], })); asset_address = extend_address_to_32(&asset_canonical); asset_chain = CHAIN_ID; // convert to normalized amounts before recording & posting vaa - amount = Uint128(amount.u128().checked_div(multiplier).unwrap()); - fee = Uint128(fee.u128().checked_div(multiplier).unwrap()); + amount = Uint128::new(amount.u128().checked_div(multiplier).unwrap()); + fee = Uint128::new(fee.u128().checked_div(multiplier).unwrap()); - send_native(&mut deps.storage, &asset_canonical, amount)?; + send_native(deps.storage, &asset_canonical, amount)?; } }; @@ -671,39 +634,32 @@ fn handle_initiate_transfer( messages.push(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: cfg.wormhole_contract, - msg: to_binary(&WormholeHandleMsg::PostMessage { + msg: to_binary(&WormholeExecuteMsg::PostMessage { message: Binary::from(token_bridge_message.serialize()), nonce, })?, // forward coins sent to this message - send: coins_after_tax(deps, env.message.sent_funds.clone())?, + funds: coins_after_tax(deps.branch(), info.funds.clone())?, })); - Ok(HandleResponse { - messages, - log: vec![ - log("transfer.token_chain", asset_chain), - log("transfer.token", hex::encode(asset_address)), - log( - "transfer.sender", - hex::encode(extend_address_to_32( - &deps.api.canonical_address(&env.message.sender)?, - )), - ), - log("transfer.recipient_chain", recipient_chain), - log("transfer.recipient", hex::encode(recipient)), - log("transfer.amount", amount), - log("transfer.nonce", nonce), - log("transfer.block_time", env.block.time), - ], - data: None, - }) + Ok(Response::new() + .add_messages(messages) + .add_attribute("transfer.token_chain", asset_chain.to_string()) + .add_attribute("transfer.token", hex::encode(asset_address)) + .add_attribute( + "transfer.sender", + hex::encode(extend_address_to_32( + &deps.api.addr_canonicalize(&info.sender.as_str())?, + )), + ) + .add_attribute("transfer.recipient_chain", recipient_chain.to_string()) + .add_attribute("transfer.recipient", hex::encode(recipient)) + .add_attribute("transfer.amount", amount.to_string()) + .add_attribute("transfer.nonce", nonce.to_string()) + .add_attribute("transfer.block_time", env.block.time.seconds().to_string())) } -pub fn query( - deps: &Extern, - msg: QueryMsg, -) -> StdResult { +pub fn query(deps: Deps, msg: QueryMsg) -> StdResult { match msg { QueryMsg::WrappedRegistry { chain, address } => { to_binary(&query_wrapped_registry(deps, chain, address.as_slice())?) @@ -711,14 +667,14 @@ pub fn query( } } -pub fn query_wrapped_registry( - deps: &Extern, +pub fn query_wrapped_registry( + deps: Deps, chain: u16, address: &[u8], ) -> StdResult { let asset_id = build_asset_id(chain, address); // Check if this asset is already deployed - match wrapped_asset_read(&deps.storage).load(&asset_id) { + match wrapped_asset_read(deps.storage).load(&asset_id) { Ok(address) => Ok(WrappedRegistryResponse { address }), Err(_) => ContractError::AssetNotFound.std_err(), } diff --git a/terra/contracts-5/token-bridge/src/msg.rs b/terra/contracts-5/token-bridge/src/msg.rs index bbb7c2a4..b85a0dc7 100644 --- a/terra/contracts-5/token-bridge/src/msg.rs +++ b/terra/contracts-5/token-bridge/src/msg.rs @@ -1,6 +1,5 @@ use cosmwasm_std::{ Binary, - HumanAddr, Uint128, }; use schemars::JsonSchema; @@ -9,8 +8,10 @@ use serde::{ Serialize, }; +type HumanAddr = String; + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InitMsg { +pub struct InstantiateMsg { // governance contract details pub gov_chain: u16, pub gov_address: Binary, @@ -21,7 +22,7 @@ pub struct InitMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum HandleMsg { +pub enum ExecuteMsg { RegisterAssetHook { asset_id: Binary, }, diff --git a/terra/contracts-5/token-bridge/src/state.rs b/terra/contracts-5/token-bridge/src/state.rs index 492ecc3b..a9a2364b 100644 --- a/terra/contracts-5/token-bridge/src/state.rs +++ b/terra/contracts-5/token-bridge/src/state.rs @@ -6,7 +6,6 @@ use serde::{ use cosmwasm_std::{ CanonicalAddr, - HumanAddr, StdError, StdResult, Storage, @@ -25,6 +24,8 @@ use cosmwasm_storage::{ use wormhole::byte_utils::ByteUtils; +type HumanAddr = String; + pub static CONFIG_KEY: &[u8] = b"config"; pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset"; pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address"; @@ -42,49 +43,49 @@ pub struct ConfigInfo { pub wrapped_asset_code_id: u64, } -pub fn config(storage: &mut S) -> Singleton { +pub fn config(storage: &mut dyn Storage) -> Singleton { singleton(storage, CONFIG_KEY) } -pub fn config_read(storage: &S) -> ReadonlySingleton { +pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { singleton_read(storage, CONFIG_KEY) } -pub fn bridge_contracts(storage: &mut S) -> Bucket> { - bucket(BRIDGE_CONTRACTS, storage) +pub fn bridge_contracts(storage: &mut dyn Storage) -> Bucket> { + bucket(storage, BRIDGE_CONTRACTS) } -pub fn bridge_contracts_read(storage: &S) -> ReadonlyBucket> { - bucket_read(BRIDGE_CONTRACTS, storage) +pub fn bridge_contracts_read(storage: &dyn Storage) -> ReadonlyBucket> { + bucket_read(storage, BRIDGE_CONTRACTS) } -pub fn wrapped_asset(storage: &mut S) -> Bucket { - bucket(WRAPPED_ASSET_KEY, storage) +pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket { + bucket(storage, WRAPPED_ASSET_KEY) } -pub fn wrapped_asset_read(storage: &S) -> ReadonlyBucket { - bucket_read(WRAPPED_ASSET_KEY, storage) +pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket { + bucket_read(storage, WRAPPED_ASSET_KEY) } -pub fn wrapped_asset_address(storage: &mut S) -> Bucket> { - bucket(WRAPPED_ASSET_ADDRESS_KEY, storage) +pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket> { + bucket(storage, WRAPPED_ASSET_ADDRESS_KEY) } -pub fn wrapped_asset_address_read(storage: &S) -> ReadonlyBucket> { - bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage) +pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket> { + bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY) } -pub fn send_native( - storage: &mut S, +pub fn send_native( + storage: &mut dyn Storage, asset_address: &CanonicalAddr, amount: Uint128, ) -> StdResult<()> { - let mut counter_bucket = bucket(NATIVE_COUNTER, storage); + let mut counter_bucket = bucket(storage, NATIVE_COUNTER); let new_total = amount + counter_bucket .load(asset_address.as_slice()) .unwrap_or(Uint128::zero()); - if new_total > Uint128(u64::MAX as u128) { + if new_total > Uint128::new(u64::MAX as u128) { return Err(StdError::generic_err( "transfer exceeds max outstanding bridged token amount", )); @@ -92,14 +93,15 @@ pub fn send_native( counter_bucket.save(asset_address.as_slice(), &new_total) } -pub fn receive_native( - storage: &mut S, +pub fn receive_native( + storage: &mut dyn Storage, asset_address: &CanonicalAddr, amount: Uint128, ) -> StdResult<()> { - let mut counter_bucket = bucket(NATIVE_COUNTER, storage); + let mut counter_bucket = bucket(storage, NATIVE_COUNTER); let total: Uint128 = counter_bucket.load(asset_address.as_slice())?; - counter_bucket.save(asset_address.as_slice(), &(total - amount)?) + let result = total.checked_sub(amount)?; + counter_bucket.save(asset_address.as_slice(), &result) } pub struct Action;