cosmwasm: Add shutdown feature flag to token bridge

This commit is contained in:
Csongor Kiss 2022-09-15 00:29:39 +01:00 committed by Paul Noel
parent 4b38dc650b
commit c22d0c222b
10 changed files with 90 additions and 86 deletions

14
cosmwasm/Cargo.lock generated
View File

@ -1508,6 +1508,20 @@ dependencies = [
"opaque-debug", "opaque-debug",
] ]
[[package]]
name = "shutdown-core-bridge-cosmwasm"
version = "0.1.0"
dependencies = [
"wormhole-bridge-terra-2",
]
[[package]]
name = "shutdown-token-bridge-cosmwasm"
version = "0.1.0"
dependencies = [
"token-bridge-terra-2",
]
[[package]] [[package]]
name = "signature" name = "signature"
version = "1.3.2" version = "1.3.2"

View File

@ -2,7 +2,9 @@
members = [ members = [
"contracts/cw20-wrapped", "contracts/cw20-wrapped",
"contracts/wormhole", "contracts/wormhole",
"contracts/shutdown-wormhole",
"contracts/token-bridge", "contracts/token-bridge",
"contracts/shutdown-token-bridge",
"contracts/mock-bridge-integration", "contracts/mock-bridge-integration",
] ]

View File

@ -0,0 +1,12 @@
[package]
name = "shutdown-token-bridge-cosmwasm"
version = "0.1.0"
authors = ["Wormhole Project Contributors"]
edition = "2018"
description = "Shutdown Wormhole token bridge on cosmwasm"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
token-bridge-terra-2 = { path = "../token-bridge", default-features = false }

View File

@ -0,0 +1 @@
pub use token_bridge_terra_2::contract;

View File

@ -0,0 +1,12 @@
[package]
name = "shutdown-core-bridge-cosmwasm"
version = "0.1.0"
authors = ["Wormhole Project Contributors"]
edition = "2018"
description = "Shutdown Wormhole core bridge on cosmwasm"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wormhole-bridge-terra-2 = { path = "../wormhole", default-features = false }

View File

@ -0,0 +1 @@
pub use wormhole::contract;

View File

@ -12,6 +12,10 @@ crate-type = ["cdylib", "rlib"]
backtraces = ["cosmwasm-std/backtraces"] backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all init/handle/query exports # use library feature to disable all init/handle/query exports
library = [] library = []
# The 'full' feature enables all non-shutdown functionality. Without the 'full' feature
# enabled, only shutdown functionality is enabled (basically governance).
full = ["wormhole-bridge-terra-2/full"]
default = ["full"]
[dependencies] [dependencies]
cosmwasm-std = { version = "1.0.0" } cosmwasm-std = { version = "1.0.0" }
@ -22,7 +26,7 @@ cw20 = "0.13.2"
cw20-base = { version = "0.13.2", features = ["library"] } cw20-base = { version = "0.13.2", features = ["library"] }
cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] } cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] }
terraswap = "2.6.1" terraswap = "2.6.1"
wormhole-bridge-terra-2 = { path = "../wormhole", features = ["library"] } wormhole-bridge-terra-2 = { path = "../wormhole", default-features = false, features = ["library"] }
thiserror = { version = "1.0.31" } thiserror = { version = "1.0.31" }
k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] }
sha3 = { version = "0.9.1", default-features = false } sha3 = { version = "0.9.1", default-features = false }

View File

@ -89,7 +89,6 @@ use crate::{
bridge_deposit, bridge_deposit,
config, config,
config_read, config_read,
config_read_legacy,
is_wrapped_asset, is_wrapped_asset,
is_wrapped_asset_read, is_wrapped_asset_read,
receive_native, receive_native,
@ -102,7 +101,6 @@ use crate::{
Action, Action,
AssetMeta, AssetMeta,
ConfigInfo, ConfigInfo,
ConfigInfoLegacy,
RegisterChain, RegisterChain,
TokenBridgeMessage, TokenBridgeMessage,
TransferInfo, TransferInfo,
@ -135,44 +133,8 @@ pub enum TransferType<A> {
/// Ok(Response::default()) /// Ok(Response::default())
/// ``` /// ```
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> { pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {
// This migration adds a new field to the [`ConfigInfo`] struct. The // This migration is not, currently, needed as the upgrade has happened successfully.
// state stored on chain has the old version, so we first parse it as
// [`ConfigInfoLegacy`], then add the new fields, and write it back as [`ConfigInfo`].
// Since the only place the contract with the legacy state is deployed is
// terra2, we just hardcode the new value here for that chain.
// 1. make sure this contract doesn't already have the new ConfigInfo struct
// in storage. Note that this check is not strictly necessary, as the
// upgrade will only be issued for terra2, and no new chains. However, it is
// good practice to ensure that migration code cannot be run twice, which
// this check achieves.
if config_read(deps.storage).load().is_ok() {
return Err(StdError::generic_err(
"Can't migrate; this contract already has a new ConfigInfo struct",
));
}
// 2. parse old state
let ConfigInfoLegacy {
gov_chain,
gov_address,
wormhole_contract,
wrapped_asset_code_id,
} = config_read_legacy(deps.storage).load()?;
// 3. store new state with terra2 values hardcoded
let chain_id = 18;
let config_info = ConfigInfo {
gov_chain,
gov_address,
wormhole_contract,
wrapped_asset_code_id,
chain_id,
};
config(deps.storage).save(&config_info)?;
Ok(Response::default()) Ok(Response::default())
} }
@ -305,10 +267,17 @@ fn parse_vaa(deps: Deps, block_time: u64, data: &Binary) -> StdResult<ParsedVAA>
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> { pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> {
match msg { match msg {
ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data),
// The following actions are disabled in "shutdown" mode
#[cfg(feature = "full")]
ExecuteMsg::RegisterAssetHook { ExecuteMsg::RegisterAssetHook {
chain, chain,
token_address, token_address,
} => handle_register_asset(deps, env, info, chain, token_address), } => handle_register_asset(deps, env, info, chain, token_address),
#[cfg(feature = "full")]
ExecuteMsg::InitiateTransfer { ExecuteMsg::InitiateTransfer {
asset, asset,
recipient_chain, recipient_chain,
@ -326,6 +295,8 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S
TransferType::WithoutPayload, TransferType::WithoutPayload,
nonce, nonce,
), ),
#[cfg(feature = "full")]
ExecuteMsg::InitiateTransferWithPayload { ExecuteMsg::InitiateTransferWithPayload {
asset, asset,
recipient_chain, recipient_chain,
@ -346,15 +317,26 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S
}, },
nonce, nonce,
), ),
#[cfg(feature = "full")]
ExecuteMsg::DepositTokens {} => deposit_tokens(deps, env, info), ExecuteMsg::DepositTokens {} => deposit_tokens(deps, env, info),
#[cfg(feature = "full")]
ExecuteMsg::WithdrawTokens { asset } => withdraw_tokens(deps, env, info, asset), ExecuteMsg::WithdrawTokens { asset } => withdraw_tokens(deps, env, info, asset),
ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data),
#[cfg(feature = "full")]
ExecuteMsg::CreateAssetMeta { asset_info, nonce } => { ExecuteMsg::CreateAssetMeta { asset_info, nonce } => {
handle_create_asset_meta(deps, env, info, asset_info, nonce) handle_create_asset_meta(deps, env, info, asset_info, nonce)
} }
#[cfg(feature = "full")]
ExecuteMsg::CompleteTransferWithPayload { data, relayer } => { ExecuteMsg::CompleteTransferWithPayload { data, relayer } => {
handle_complete_transfer_with_payload(deps, env, info, &data, &relayer) handle_complete_transfer_with_payload(deps, env, info, &data, &relayer)
} }
// When in "shutdown" mode, we reject any other action
#[cfg(not(feature = "full"))]
_ => Err(StdError::generic_err("Invalid during shutdown mode"))
} }
} }
@ -709,6 +691,9 @@ fn submit_vaa(
let (vaa, payload) = parse_and_archive_vaa(deps.branch(), env.clone(), data)?; let (vaa, payload) = parse_and_archive_vaa(deps.branch(), env.clone(), data)?;
match payload { match payload {
Either::Left(governance_packet) => handle_governance_payload(deps, env, &governance_packet), Either::Left(governance_packet) => handle_governance_payload(deps, env, &governance_packet),
// In "shutdown" mode, we only handle governance payloads
#[cfg(feature = "full")]
Either::Right(message) => match message.action { Either::Right(message) => match message.action {
Action::TRANSFER => { Action::TRANSFER => {
let sender = info.sender.to_string(); let sender = info.sender.to_string();
@ -733,6 +718,9 @@ fn submit_vaa(
), ),
_ => ContractError::InvalidVAAAction.std_err(), _ => ContractError::InvalidVAAAction.std_err(),
}, },
#[cfg(not(feature = "full"))]
_ => ContractError::InvalidVAAAction.std_err(),
} }
} }

View File

@ -13,6 +13,10 @@ crate-type = ["cdylib", "rlib"]
backtraces = ["cosmwasm-std/backtraces"] backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all init/handle/query exports # use library feature to disable all init/handle/query exports
library = [] library = []
# The 'full' feature enables all non-shutdown functionality. Without the 'full' feature
# enabled, only shutdown functionality is enabled (basically governance).
full = []
default = ["full"]
[dependencies] [dependencies]
cosmwasm-std = { version = "1.0.0" } cosmwasm-std = { version = "1.0.0" }

View File

@ -37,7 +37,6 @@ use crate::{
state::{ state::{
config, config,
config_read, config_read,
config_read_legacy,
guardian_set_get, guardian_set_get,
guardian_set_set, guardian_set_set,
sequence_read, sequence_read,
@ -45,7 +44,6 @@ use crate::{
vaa_archive_add, vaa_archive_add,
vaa_archive_check, vaa_archive_check,
ConfigInfo, ConfigInfo,
ConfigInfoLegacy,
ContractUpgrade, ContractUpgrade,
GovernancePacket, GovernancePacket,
GuardianAddress, GuardianAddress,
@ -91,48 +89,8 @@ const FEE_AMOUNT: u128 = 0;
/// Ok(Response::default()) /// Ok(Response::default())
/// ``` /// ```
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> { pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {
// This migration adds two new fields to the [`ConfigInfo`] struct. The // This migration is not, currently, needed as the upgrade has happened successfully.
// state stored on chain has the old version, so we first parse it as
// [`ConfigInfoLegacy`], then add the new fields, and write it back as [`ConfigInfo`].
// Since the only place the contract with the legacy state is deployed is
// terra2, we just hardcode the new values here for that chain.
// 1. make sure this contract doesn't already have the new ConfigInfo struct
// in storage. Note that this check is not strictly necessary, as the
// upgrade will only be issued for terra2, and no new chains. However, it is
// good practice to ensure that migration code cannot be run twice, which
// this check achieves.
if config_read(deps.storage).load().is_ok() {
return Err(StdError::generic_err(
"Can't migrate; this contract already has a new ConfigInfo struct",
));
}
// 2. parse old state
let ConfigInfoLegacy {
guardian_set_index,
guardian_set_expirity,
gov_chain,
gov_address,
fee,
} = config_read_legacy(deps.storage).load()?;
// 3. store new state with terra2 values hardcoded
let chain_id = 18;
let fee_denom = "uluna".to_string();
let config_info = ConfigInfo {
guardian_set_index,
guardian_set_expirity,
gov_chain,
gov_address,
fee,
chain_id,
fee_denom,
};
config(deps.storage).save(&config_info)?;
Ok(Response::default()) Ok(Response::default())
// NOTE: once this migration has successfully completed, the contents of // NOTE: once this migration has successfully completed, the contents of
// this (`migrate`) function should be deleted, along with the // this (`migrate`) function should be deleted, along with the
@ -172,10 +130,16 @@ pub fn instantiate(
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> { pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> {
match msg { match msg {
#[cfg(feature = "full")]
ExecuteMsg::PostMessage { message, nonce } => { ExecuteMsg::PostMessage { message, nonce } => {
handle_post_message(deps, env, info, message.as_slice(), nonce) handle_post_message(deps, env, info, message.as_slice(), nonce)
} }
ExecuteMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, info, vaa.as_slice()), ExecuteMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, info, vaa.as_slice()),
// When in "shutdown" mode, we reject any other action
#[cfg(not(feature = "full"))]
_ => Err(StdError::generic_err("Invalid during shutdown mode"))
} }
} }
@ -223,7 +187,9 @@ fn handle_governance_payload(deps: DepsMut, env: Env, data: &[u8]) -> StdResult<
match gov_packet.action { match gov_packet.action {
1u8 => vaa_update_contract(deps, env, &gov_packet.payload), 1u8 => vaa_update_contract(deps, env, &gov_packet.payload),
2u8 => vaa_update_guardian_set(deps, env, &gov_packet.payload), 2u8 => vaa_update_guardian_set(deps, env, &gov_packet.payload),
#[cfg(feature = "full")]
3u8 => handle_set_fee(deps, env, &gov_packet.payload), 3u8 => handle_set_fee(deps, env, &gov_packet.payload),
#[cfg(feature = "full")]
4u8 => handle_transfer_fee(deps, env, &gov_packet.payload), 4u8 => handle_transfer_fee(deps, env, &gov_packet.payload),
_ => ContractError::InvalidVAAAction.std_err(), _ => ContractError::InvalidVAAAction.std_err(),
} }