diff --git a/cosmwasm/Cargo.lock b/cosmwasm/Cargo.lock index 08015d420..c540a0bd0 100644 --- a/cosmwasm/Cargo.lock +++ b/cosmwasm/Cargo.lock @@ -1508,6 +1508,20 @@ dependencies = [ "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]] name = "signature" version = "1.3.2" diff --git a/cosmwasm/Cargo.toml b/cosmwasm/Cargo.toml index 092eb77a9..a794f7653 100644 --- a/cosmwasm/Cargo.toml +++ b/cosmwasm/Cargo.toml @@ -2,7 +2,9 @@ members = [ "contracts/cw20-wrapped", "contracts/wormhole", + "contracts/shutdown-wormhole", "contracts/token-bridge", + "contracts/shutdown-token-bridge", "contracts/mock-bridge-integration", ] diff --git a/cosmwasm/contracts/shutdown-token-bridge/Cargo.toml b/cosmwasm/contracts/shutdown-token-bridge/Cargo.toml new file mode 100644 index 000000000..d0568cbb8 --- /dev/null +++ b/cosmwasm/contracts/shutdown-token-bridge/Cargo.toml @@ -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 } diff --git a/cosmwasm/contracts/shutdown-token-bridge/src/lib.rs b/cosmwasm/contracts/shutdown-token-bridge/src/lib.rs new file mode 100644 index 000000000..d020c3b2c --- /dev/null +++ b/cosmwasm/contracts/shutdown-token-bridge/src/lib.rs @@ -0,0 +1 @@ +pub use token_bridge_terra_2::contract; diff --git a/cosmwasm/contracts/shutdown-wormhole/Cargo.toml b/cosmwasm/contracts/shutdown-wormhole/Cargo.toml new file mode 100644 index 000000000..0a14809af --- /dev/null +++ b/cosmwasm/contracts/shutdown-wormhole/Cargo.toml @@ -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 } diff --git a/cosmwasm/contracts/shutdown-wormhole/src/lib.rs b/cosmwasm/contracts/shutdown-wormhole/src/lib.rs new file mode 100644 index 000000000..47f4c58ab --- /dev/null +++ b/cosmwasm/contracts/shutdown-wormhole/src/lib.rs @@ -0,0 +1 @@ +pub use wormhole::contract; diff --git a/cosmwasm/contracts/token-bridge/Cargo.toml b/cosmwasm/contracts/token-bridge/Cargo.toml index 68721eb82..5bb2cc11e 100644 --- a/cosmwasm/contracts/token-bridge/Cargo.toml +++ b/cosmwasm/contracts/token-bridge/Cargo.toml @@ -12,6 +12,10 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all init/handle/query exports 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] cosmwasm-std = { version = "1.0.0" } @@ -22,7 +26,7 @@ cw20 = "0.13.2" cw20-base = { version = "0.13.2", features = ["library"] } cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] } 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" } k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } sha3 = { version = "0.9.1", default-features = false } diff --git a/cosmwasm/contracts/token-bridge/src/contract.rs b/cosmwasm/contracts/token-bridge/src/contract.rs index 81ce3b988..60162468e 100644 --- a/cosmwasm/contracts/token-bridge/src/contract.rs +++ b/cosmwasm/contracts/token-bridge/src/contract.rs @@ -89,7 +89,6 @@ use crate::{ bridge_deposit, config, config_read, - config_read_legacy, is_wrapped_asset, is_wrapped_asset_read, receive_native, @@ -102,7 +101,6 @@ use crate::{ Action, AssetMeta, ConfigInfo, - ConfigInfoLegacy, RegisterChain, TokenBridgeMessage, TransferInfo, @@ -135,44 +133,8 @@ pub enum TransferType { /// Ok(Response::default()) /// ``` #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { - // This migration adds a new field to the [`ConfigInfo`] struct. The - // 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)?; +pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { + // This migration is not, currently, needed as the upgrade has happened successfully. Ok(Response::default()) } @@ -305,10 +267,17 @@ fn parse_vaa(deps: Deps, block_time: u64, data: &Binary) -> StdResult #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { + ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data), + + // The following actions are disabled in "shutdown" mode + + #[cfg(feature = "full")] ExecuteMsg::RegisterAssetHook { chain, token_address, } => handle_register_asset(deps, env, info, chain, token_address), + + #[cfg(feature = "full")] ExecuteMsg::InitiateTransfer { asset, recipient_chain, @@ -326,6 +295,8 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S TransferType::WithoutPayload, nonce, ), + + #[cfg(feature = "full")] ExecuteMsg::InitiateTransferWithPayload { asset, recipient_chain, @@ -346,15 +317,26 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S }, nonce, ), + + #[cfg(feature = "full")] ExecuteMsg::DepositTokens {} => deposit_tokens(deps, env, info), + + #[cfg(feature = "full")] 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 } => { handle_create_asset_meta(deps, env, info, asset_info, nonce) } + + #[cfg(feature = "full")] ExecuteMsg::CompleteTransferWithPayload { 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)?; match payload { 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 { Action::TRANSFER => { let sender = info.sender.to_string(); @@ -733,6 +718,9 @@ fn submit_vaa( ), _ => ContractError::InvalidVAAAction.std_err(), }, + + #[cfg(not(feature = "full"))] + _ => ContractError::InvalidVAAAction.std_err(), } } diff --git a/cosmwasm/contracts/wormhole/Cargo.toml b/cosmwasm/contracts/wormhole/Cargo.toml index 0ec7ef873..070cbc8e2 100644 --- a/cosmwasm/contracts/wormhole/Cargo.toml +++ b/cosmwasm/contracts/wormhole/Cargo.toml @@ -13,6 +13,10 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all init/handle/query exports 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] cosmwasm-std = { version = "1.0.0" } diff --git a/cosmwasm/contracts/wormhole/src/contract.rs b/cosmwasm/contracts/wormhole/src/contract.rs index c7b728a23..8971358ee 100644 --- a/cosmwasm/contracts/wormhole/src/contract.rs +++ b/cosmwasm/contracts/wormhole/src/contract.rs @@ -37,7 +37,6 @@ use crate::{ state::{ config, config_read, - config_read_legacy, guardian_set_get, guardian_set_set, sequence_read, @@ -45,7 +44,6 @@ use crate::{ vaa_archive_add, vaa_archive_check, ConfigInfo, - ConfigInfoLegacy, ContractUpgrade, GovernancePacket, GuardianAddress, @@ -91,48 +89,8 @@ const FEE_AMOUNT: u128 = 0; /// Ok(Response::default()) /// ``` #[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { - // This migration adds two new fields to the [`ConfigInfo`] struct. The - // 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)?; +pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { + // This migration is not, currently, needed as the upgrade has happened successfully. Ok(Response::default()) // NOTE: once this migration has successfully completed, the contents of // this (`migrate`) function should be deleted, along with the @@ -172,10 +130,16 @@ pub fn instantiate( #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { + #[cfg(feature = "full")] ExecuteMsg::PostMessage { message, nonce } => { handle_post_message(deps, env, info, message.as_slice(), nonce) } + 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 { 1u8 => vaa_update_contract(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), + #[cfg(feature = "full")] 4u8 => handle_transfer_fee(deps, env, &gov_packet.payload), _ => ContractError::InvalidVAAAction.std_err(), }