Procházet zdrojové kódy

terra: columbus-5 contracts by default

Change-Id: I007689b032c6182e35421b47b56787a657a6919c
Reisen před 4 roky
rodič
revize
b662de4efb
47 změnil soubory, kde provedl 1344 přidání a 4238 odebrání
  1. 400 220
      terra/Cargo.lock
  2. 1 1
      terra/Cargo.toml
  3. 1 1
      terra/Dockerfile
  4. binární
      terra/artifacts/cw20_base.wasm
  5. 0 3
      terra/contracts-5/README.md
  6. 0 5
      terra/contracts-5/cw20-wrapped/.cargo/config
  7. 0 28
      terra/contracts-5/cw20-wrapped/Cargo.toml
  8. 0 374
      terra/contracts-5/cw20-wrapped/src/contract.rs
  9. 0 27
      terra/contracts-5/cw20-wrapped/src/error.rs
  10. 0 7
      terra/contracts-5/cw20-wrapped/src/lib.rs
  11. 0 122
      terra/contracts-5/cw20-wrapped/src/msg.rs
  12. 0 37
      terra/contracts-5/cw20-wrapped/src/state.rs
  13. 0 253
      terra/contracts-5/cw20-wrapped/tests/integration.rs
  14. 0 5
      terra/contracts-5/token-bridge/.cargo/config
  15. 0 36
      terra/contracts-5/token-bridge/Cargo.toml
  16. 0 733
      terra/contracts-5/token-bridge/src/contract.rs
  17. 0 10
      terra/contracts-5/token-bridge/src/lib.rs
  18. 0 71
      terra/contracts-5/token-bridge/src/msg.rs
  19. 0 249
      terra/contracts-5/token-bridge/src/state.rs
  20. 0 114
      terra/contracts-5/token-bridge/tests/integration.rs
  21. 0 5
      terra/contracts-5/wormhole/.cargo/config
  22. 0 33
      terra/contracts-5/wormhole/Cargo.toml
  23. 0 76
      terra/contracts-5/wormhole/src/byte_utils.rs
  24. 0 387
      terra/contracts-5/wormhole/src/contract.rs
  25. 0 113
      terra/contracts-5/wormhole/src/error.rs
  26. 0 7
      terra/contracts-5/wormhole/src/lib.rs
  27. 0 66
      terra/contracts-5/wormhole/src/msg.rs
  28. 0 444
      terra/contracts-5/wormhole/src/state.rs
  29. 8 6
      terra/contracts/cw20-wrapped/Cargo.toml
  30. 150 134
      terra/contracts/cw20-wrapped/src/contract.rs
  31. 2 4
      terra/contracts/cw20-wrapped/src/lib.rs
  32. 8 6
      terra/contracts/cw20-wrapped/src/msg.rs
  33. 4 5
      terra/contracts/cw20-wrapped/src/state.rs
  34. 9 10
      terra/contracts/token-bridge/Cargo.toml
  35. 245 318
      terra/contracts/token-bridge/src/contract.rs
  36. 0 4
      terra/contracts/token-bridge/src/lib.rs
  37. 10 4
      terra/contracts/token-bridge/src/msg.rs
  38. 29 27
      terra/contracts/token-bridge/src/state.rs
  39. 9 8
      terra/contracts/wormhole/Cargo.toml
  40. 113 138
      terra/contracts/wormhole/src/contract.rs
  41. 0 1
      terra/contracts/wormhole/src/error.rs
  42. 0 3
      terra/contracts/wormhole/src/lib.rs
  43. 9 3
      terra/contracts/wormhole/src/msg.rs
  44. 42 27
      terra/contracts/wormhole/src/state.rs
  45. 170 113
      terra/tools/deploy.js
  46. 1 0
      terra/tools/deploy.sh
  47. 133 0
      terra/tools/migrate.js

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 400 - 220
terra/Cargo.lock


+ 1 - 1
terra/Cargo.toml

@@ -10,4 +10,4 @@ debug-assertions = false
 codegen-units = 1
 panic = 'abort'
 incremental = false
-overflow-checks = true
+overflow-checks = true

+ 1 - 1
terra/Dockerfile

@@ -1,6 +1,6 @@
 # This is a multi-stage docker file, first stage builds contracts
 # And the second one creates node.js environment to deploy them
-FROM cosmwasm/workspace-optimizer:0.10.4@sha256:a976db4ee7add887a6af26724b804bbd9e9d534554506447e72ac57e65357db9 AS builder
+FROM cosmwasm/workspace-optimizer:0.12.1@sha256:1508cf7545f4b656ecafa34e29c1acf200cdab47fced85c2bc076c0c158b1338 AS builder
 ADD Cargo.lock /code/
 ADD Cargo.toml /code/
 ADD contracts /code/contracts

binární
terra/artifacts/cw20_base.wasm


+ 0 - 3
terra/contracts-5/README.md

@@ -1,3 +0,0 @@
-# Terra Wormhole Contracts
-
-The Wormhole Terra integration is developed and maintained by Everstake / @ysavchenko.

+ 0 - 5
terra/contracts-5/cw20-wrapped/.cargo/config

@@ -1,5 +0,0 @@
-[alias]
-wasm = "build --release --target wasm32-unknown-unknown"
-wasm-debug = "build --target wasm32-unknown-unknown"
-unit-test = "test --lib --features backtraces"
-integration-test = "test --test integration"

+ 0 - 28
terra/contracts-5/cw20-wrapped/Cargo.toml

@@ -1,28 +0,0 @@
-[package]
-name = "cw20-wrapped"
-version = "0.1.0"
-authors = ["Yuriy Savchenko <yuriy.savchenko@gmail.com>"]
-edition = "2018"
-description = "Wrapped CW20 token contract"
-
-[lib]
-crate-type = ["cdylib", "rlib"]
-
-[features]
-backtraces = ["cosmwasm-std/backtraces"]
-# use library feature to disable all init/handle/query exports
-library = []
-
-[dependencies]
-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"] }
-cw2 = { version = "0.8.0" } 
-cw20 = { version = "0.8.0" } 
-cw20-legacy = { version = "0.2.0", features = ["library"]} 
-cw-storage-plus  = { version = "0.8.0" }
-thiserror = { version = "1.0.20" }
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.16.0", default-features = false }

+ 0 - 374
terra/contracts-5/cw20-wrapped/src/contract.rs

@@ -1,374 +0,0 @@
-use cosmwasm_std::{
-    entry_point,
-    to_binary,
-    Binary,
-    CosmosMsg,
-    Deps,
-    DepsMut,
-    Env,
-    MessageInfo,
-    Response,
-    StdError,
-    StdResult,
-    Uint128,
-    WasmMsg,
-};
-
-use cw2::set_contract_version;
-use cw20_legacy::{
-    allowances::{
-        execute_burn_from,
-        execute_decrease_allowance,
-        execute_increase_allowance,
-        execute_send_from,
-        execute_transfer_from,
-        query_allowance,
-    },
-    contract::{
-        execute_mint,
-        execute_send,
-        execute_transfer,
-        query_balance,
-    },
-    state::{
-        MinterData,
-        TokenInfo,
-        TOKEN_INFO,
-    },
-    ContractError,
-};
-
-use crate::{
-    msg::{
-        ExecuteMsg,
-        InstantiateMsg,
-        QueryMsg,
-        WrappedAssetInfoResponse,
-    },
-    state::{
-        wrapped_asset_info,
-        wrapped_asset_info_read,
-        WrappedAssetInfo,
-    },
-};
-use cw20::TokenInfoResponse;
-use std::string::String;
-
-type HumanAddr = String;
-
-// version info for migration info
-const CONTRACT_NAME: &str = "crates.io:cw20-base";
-const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn instantiate(
-    deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    msg: InstantiateMsg,
-) -> StdResult<Response> {
-    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
-
-    // store token info using cw20-base format
-    let data = TokenInfo {
-        name: msg.name,
-        symbol: msg.symbol,
-        decimals: msg.decimals,
-        total_supply: Uint128::new(0),
-        // set creator as minter
-        mint: Some(MinterData {
-            minter: deps.api.addr_canonicalize(&info.sender.as_str())?,
-            cap: None,
-        }),
-    };
-    TOKEN_INFO.save(deps.storage, &data)?;
-
-    // save wrapped asset info
-    let data = WrappedAssetInfo {
-        asset_chain: msg.asset_chain,
-        asset_address: msg.asset_address,
-        bridge: deps.api.addr_canonicalize(&info.sender.as_str())?,
-    };
-    wrapped_asset_info(deps.storage).save(&data)?;
-
-    if let Some(mint_info) = msg.mint {
-        execute_mint(deps, env, info, mint_info.recipient, mint_info.amount)
-            .map_err(|e| StdError::generic_err(format!("{}", e)))?;
-    }
-
-    if let Some(hook) = msg.init_hook {
-        Ok(
-            Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute {
-                contract_addr: hook.contract_addr,
-                msg: hook.msg,
-                funds: vec![],
-            })),
-        )
-    } else {
-        Ok(Response::default())
-    }
-}
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn execute(
-    deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    msg: ExecuteMsg,
-) -> Result<Response, ContractError> {
-    match msg {
-        // these all come from cw20-base to implement the cw20 standard
-        ExecuteMsg::Transfer { recipient, amount } => {
-            Ok(execute_transfer(deps, env, info, recipient, amount)?)
-        }
-        ExecuteMsg::Burn { account, amount } => {
-            Ok(execute_burn_from(deps, env, info, account, amount)?)
-        }
-        ExecuteMsg::Send {
-            contract,
-            amount,
-            msg,
-        } => Ok(execute_send(deps, env, info, contract, amount, msg)?),
-        ExecuteMsg::Mint { recipient, amount } => {
-            execute_mint_wrapped(deps, env, info, recipient, amount)
-        }
-        ExecuteMsg::IncreaseAllowance {
-            spender,
-            amount,
-            expires,
-        } => Ok(execute_increase_allowance(
-            deps, env, info, spender, amount, expires,
-        )?),
-        ExecuteMsg::DecreaseAllowance {
-            spender,
-            amount,
-            expires,
-        } => Ok(execute_decrease_allowance(
-            deps, env, info, spender, amount, expires,
-        )?),
-        ExecuteMsg::TransferFrom {
-            owner,
-            recipient,
-            amount,
-        } => Ok(execute_transfer_from(
-            deps, env, info, owner, recipient, amount,
-        )?),
-        ExecuteMsg::BurnFrom { owner, amount } => {
-            Ok(execute_burn_from(deps, env, info, owner, amount)?)
-        }
-        ExecuteMsg::SendFrom {
-            owner,
-            contract,
-            amount,
-            msg,
-        } => Ok(execute_send_from(
-            deps, env, info, owner, contract, amount, msg,
-        )?),
-    }
-}
-
-fn execute_mint_wrapped(
-    deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    recipient: HumanAddr,
-    amount: Uint128,
-) -> Result<Response, ContractError> {
-    // Only bridge can mint
-    let wrapped_info = wrapped_asset_info_read(deps.storage).load()?;
-    if wrapped_info.bridge != deps.api.addr_canonicalize(&info.sender.as_str())? {
-        return Err(ContractError::Unauthorized {});
-    }
-
-    Ok(execute_mint(deps, env, info, recipient, amount)?)
-}
-
-pub fn query(deps: Deps, msg: QueryMsg) -> StdResult<Binary> {
-    match msg {
-        QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?),
-        // inherited from cw20-base
-        QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?),
-        QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?),
-        QueryMsg::Allowance { owner, spender } => {
-            to_binary(&query_allowance(deps, owner, spender)?)
-        }
-    }
-}
-
-pub fn query_token_info(deps: Deps) -> StdResult<TokenInfoResponse> {
-    let info = TOKEN_INFO.load(deps.storage)?;
-    Ok(TokenInfoResponse {
-        name: String::from("Wormhole:") + info.name.as_str(),
-        symbol: String::from("wh") + info.symbol.as_str(),
-        decimals: info.decimals,
-        total_supply: info.total_supply,
-    })
-}
-
-pub fn query_wrapped_asset_info(deps: Deps) -> StdResult<WrappedAssetInfoResponse> {
-    let info = wrapped_asset_info_read(deps.storage).load()?;
-    Ok(WrappedAssetInfoResponse {
-        asset_chain: info.asset_chain,
-        asset_address: info.asset_address,
-        bridge: deps.api.addr_humanize(&info.bridge)?,
-    })
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use cosmwasm_std::testing::{
-        mock_dependencies,
-        mock_env,
-        mock_info,
-    };
-    use cw20::TokenInfoResponse;
-
-    const CANONICAL_LENGTH: usize = 20;
-
-    fn get_balance(deps: Deps, address: HumanAddr) -> Uint128 {
-        query_balance(deps, address.into()).unwrap().balance
-    }
-
-    fn do_init(mut deps: DepsMut, creator: &HumanAddr) {
-        let init_msg = InstantiateMsg {
-            name: "Integers".to_string(),
-            symbol: "INT".to_string(),
-            asset_chain: 1,
-            asset_address: vec![1; 32].into(),
-            decimals: 10,
-            mint: None,
-            init_hook: None,
-        };
-        let env = mock_env();
-        let info = mock_info(creator, &[]);
-        let res = instantiate(deps, env, info, init_msg).unwrap();
-        assert_eq!(0, res.messages.len());
-
-        assert_eq!(
-            query_token_info(deps.as_ref()).unwrap(),
-            TokenInfoResponse {
-                name: "Wormhole Wrapped".to_string(),
-                symbol: "WWT".to_string(),
-                decimals: 10,
-                total_supply: Uint128::from(0u128),
-            }
-        );
-
-        assert_eq!(
-            query_wrapped_asset_info(deps.as_ref()).unwrap(),
-            WrappedAssetInfoResponse {
-                asset_chain: 1,
-                asset_address: vec![1; 32].into(),
-                bridge: deps.api.addr_validate(creator).unwrap(),
-            }
-        );
-    }
-
-    fn do_init_and_mint(
-        mut deps: DepsMut,
-        creator: &HumanAddr,
-        mint_to: &HumanAddr,
-        amount: Uint128,
-    ) {
-        do_init(deps, creator);
-
-        let msg = ExecuteMsg::Mint {
-            recipient: mint_to.clone(),
-            amount,
-        };
-
-        let env = mock_env();
-        let info = mock_info(creator, &[]);
-        let res = execute(deps.as_mut(), env, info, msg.clone()).unwrap();
-        assert_eq!(0, res.messages.len());
-        assert_eq!(get_balance(deps.as_ref(), mint_to.clone(),), amount);
-
-        assert_eq!(
-            query_token_info(deps.as_ref()).unwrap(),
-            TokenInfoResponse {
-                name: "Wormhole Wrapped".to_string(),
-                symbol: "WWT".to_string(),
-                decimals: 10,
-                total_supply: amount,
-            }
-        );
-    }
-
-    #[test]
-    fn can_mint_by_minter() {
-        let mut deps = mock_dependencies(&[]);
-        let minter = HumanAddr::from("minter");
-        let recipient = HumanAddr::from("recipient");
-        let amount = Uint128::new(222_222_222);
-        do_init_and_mint(deps.as_mut(), &minter, &recipient, amount);
-    }
-
-    #[test]
-    fn others_cannot_mint() {
-        let mut deps = mock_dependencies(&[]);
-        let minter = HumanAddr::from("minter");
-        let recipient = HumanAddr::from("recipient");
-        do_init(deps.as_mut(), &minter);
-
-        let amount = Uint128::new(222_222_222);
-        let msg = ExecuteMsg::Mint {
-            recipient: recipient.clone(),
-            amount,
-        };
-
-        let other_address = HumanAddr::from("other");
-        let env = mock_env();
-        let info = mock_info(&other_address, &[]);
-        let res = execute(deps.as_mut(), env, info, msg);
-        assert_eq!(
-            format!("{}", res.unwrap_err()),
-            format!("{}", crate::error::ContractError::Unauthorized {})
-        );
-    }
-
-    #[test]
-    fn transfer_balance_success() {
-        let mut deps = mock_dependencies(&[]);
-        let minter = HumanAddr::from("minter");
-        let owner = HumanAddr::from("owner");
-        let amount_initial = Uint128::new(222_222_222);
-        do_init_and_mint(deps.as_mut(), &minter, &owner, amount_initial);
-
-        // Transfer
-        let recipient = HumanAddr::from("recipient");
-        let amount_transfer = Uint128::new(222_222);
-        let msg = ExecuteMsg::Transfer {
-            recipient: recipient.clone(),
-            amount: amount_transfer,
-        };
-
-        let env = mock_env();
-        let info = mock_info(&owner, &[]);
-        let res = execute(deps.as_mut(), env, info, msg.clone()).unwrap();
-        assert_eq!(0, res.messages.len());
-        assert_eq!(get_balance(deps.as_ref(), owner), Uint128::new(222_000_000));
-        assert_eq!(get_balance(deps.as_ref(), recipient), amount_transfer);
-    }
-
-    #[test]
-    fn transfer_balance_not_enough() {
-        let mut deps = mock_dependencies(&[]);
-        let minter = HumanAddr::from("minter");
-        let owner = HumanAddr::from("owner");
-        let amount_initial = Uint128::new(222_221);
-        do_init_and_mint(deps.as_mut(), &minter, &owner, amount_initial);
-
-        // Transfer
-        let recipient = HumanAddr::from("recipient");
-        let amount_transfer = Uint128::new(222_222);
-        let msg = ExecuteMsg::Transfer {
-            recipient: recipient.clone(),
-            amount: amount_transfer,
-        };
-
-        let env = mock_env();
-        let info = mock_info(&owner, &[]);
-        let _ = execute(deps.as_mut(), env, info, msg.clone()).unwrap_err(); // Will panic if no error
-    }
-}

+ 0 - 27
terra/contracts-5/cw20-wrapped/src/error.rs

@@ -1,27 +0,0 @@
-use cosmwasm_std::StdError;
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum ContractError {
-    // CW20 errors
-    #[error("{0}")]
-    Std(#[from] StdError),
-
-    #[error("Unauthorized")]
-    Unauthorized {},
-
-    #[error("Cannot set to own account")]
-    CannotSetOwnAccount {},
-
-    #[error("Invalid zero amount")]
-    InvalidZeroAmount {},
-
-    #[error("Allowance is expired")]
-    Expired {},
-
-    #[error("No allowance for this account")]
-    NoAllowance {},
-
-    #[error("Minting cannot exceed the cap")]
-    CannotExceedCap {},
-}

+ 0 - 7
terra/contracts-5/cw20-wrapped/src/lib.rs

@@ -1,7 +0,0 @@
-mod error;
-
-pub mod contract;
-pub mod msg;
-pub mod state;
-
-pub use crate::error::ContractError;

+ 0 - 122
terra/contracts-5/cw20-wrapped/src/msg.rs

@@ -1,122 +0,0 @@
-#![allow(clippy::field_reassign_with_default)]
-use schemars::JsonSchema;
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-use cosmwasm_std::{
-    Addr,
-    Binary,
-    Uint128,
-};
-use cw20::Expiration;
-
-type HumanAddr = String;
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InstantiateMsg {
-    pub name: String,
-    pub symbol: String,
-    pub asset_chain: u16,
-    pub asset_address: Binary,
-    pub decimals: u8,
-    pub mint: Option<InitMint>,
-    pub init_hook: Option<InitHook>,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InitHook {
-    pub msg: Binary,
-    pub contract_addr: HumanAddr,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InitMint {
-    pub recipient: HumanAddr,
-    pub amount: Uint128,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum ExecuteMsg {
-    /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions
-    Transfer {
-        recipient: HumanAddr,
-        amount: Uint128,
-    },
-    /// Slightly different than CW20. Burn is a base message to destroy tokens forever
-    Burn { account: HumanAddr, amount: Uint128 },
-    /// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action
-    /// on the receiving contract.
-    Send {
-        contract: HumanAddr,
-        amount: Uint128,
-        msg: Binary,
-    },
-    /// Implements CW20 "mintable" extension. If authorized, creates amount new tokens
-    /// and adds to the recipient balance.
-    Mint {
-        recipient: HumanAddr,
-        amount: Uint128,
-    },
-    /// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens
-    /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance
-    /// expiration with this one.
-    IncreaseAllowance {
-        spender: HumanAddr,
-        amount: Uint128,
-        expires: Option<Expiration>,
-    },
-    /// Implements CW20 "approval" extension. Lowers the spender's access of tokens
-    /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current
-    /// allowance expiration with this one.
-    DecreaseAllowance {
-        spender: HumanAddr,
-        amount: Uint128,
-        expires: Option<Expiration>,
-    },
-    /// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient
-    /// if `env.sender` has sufficient pre-approval.
-    TransferFrom {
-        owner: HumanAddr,
-        recipient: HumanAddr,
-        amount: Uint128,
-    },
-    /// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract
-    /// if `env.sender` has sufficient pre-approval.
-    SendFrom {
-        owner: HumanAddr,
-        contract: HumanAddr,
-        amount: Uint128,
-        msg: Binary,
-    },
-    /// Implements CW20 "approval" extension. Destroys tokens forever
-    BurnFrom { owner: HumanAddr, amount: Uint128 },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum QueryMsg {
-    // Generic information about the wrapped asset
-    WrappedAssetInfo {},
-    /// Implements CW20. Returns the current balance of the given address, 0 if unset.
-    Balance {
-        address: HumanAddr,
-    },
-    /// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.
-    TokenInfo {},
-    /// Implements CW20 "allowance" extension.
-    /// Returns how much spender can use from owner account, 0 if unset.
-    Allowance {
-        owner: HumanAddr,
-        spender: HumanAddr,
-    },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct WrappedAssetInfoResponse {
-    pub asset_chain: u16,      // Asset chain id
-    pub asset_address: Binary, // Asset smart contract address in the original chain
-    pub bridge: Addr,          // Bridge address, authorized to mint and burn wrapped tokens
-}

+ 0 - 37
terra/contracts-5/cw20-wrapped/src/state.rs

@@ -1,37 +0,0 @@
-use schemars::JsonSchema;
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-use cosmwasm_std::{
-    Binary,
-    CanonicalAddr,
-    Storage,
-};
-use cosmwasm_storage::{
-    singleton,
-    singleton_read,
-    ReadonlySingleton,
-    Singleton,
-};
-
-pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset";
-
-// Created at initialization and reference original asset and bridge address
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct WrappedAssetInfo {
-    pub asset_chain: u16,      // Asset chain id
-    pub asset_address: Binary, // Asset smart contract address on the original chain
-    pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens
-}
-
-pub fn wrapped_asset_info(storage: &mut dyn Storage) -> Singleton<WrappedAssetInfo> {
-    singleton(storage, KEY_WRAPPED_ASSET)
-}
-
-pub fn wrapped_asset_info_read(
-    storage: &dyn Storage,
-) -> ReadonlySingleton<WrappedAssetInfo> {
-    singleton_read(storage, KEY_WRAPPED_ASSET)
-}

+ 0 - 253
terra/contracts-5/cw20-wrapped/tests/integration.rs

@@ -1,253 +0,0 @@
-static WASM: &[u8] =
-    include_bytes!("../../../target/wasm32-unknown-unknown/release/cw20_wrapped.wasm");
-
-use cosmwasm_std::{
-    from_slice,
-    Binary,
-    Env,
-    HandleResponse,
-    HandleResult,
-    HumanAddr,
-    InitResponse,
-    Uint128,
-};
-use cosmwasm_storage::to_length_prefixed;
-use cosmwasm_vm::{
-    testing::{
-        handle,
-        init,
-        mock_env,
-        mock_instance,
-        query,
-        MockApi,
-        MockQuerier,
-        MockStorage,
-    },
-    Api,
-    Instance,
-    Storage,
-};
-use cw20_wrapped::{
-    msg::{
-        HandleMsg,
-        InitMsg,
-        QueryMsg,
-    },
-    state::{
-        WrappedAssetInfo,
-        KEY_WRAPPED_ASSET,
-    },
-    ContractError,
-};
-
-enum TestAddress {
-    INITIALIZER,
-    RECIPIENT,
-    SENDER,
-}
-
-impl TestAddress {
-    fn value(&self) -> HumanAddr {
-        match self {
-            TestAddress::INITIALIZER => HumanAddr::from("addr0000"),
-            TestAddress::RECIPIENT => HumanAddr::from("addr2222"),
-            TestAddress::SENDER => HumanAddr::from("addr3333"),
-        }
-    }
-}
-
-fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env {
-    let mut env = mock_env(signer, &[]);
-    env.block.height = height;
-    env.block.time = time;
-    env
-}
-
-fn get_wrapped_asset_info<S: Storage>(storage: &S) -> WrappedAssetInfo {
-    let key = to_length_prefixed(KEY_WRAPPED_ASSET);
-    let data = storage
-        .get(&key)
-        .0
-        .expect("error getting data")
-        .expect("data should exist");
-    from_slice(&data).expect("invalid data")
-}
-
-fn do_init(height: u64) -> Instance<MockStorage, MockApi, MockQuerier> {
-    let mut deps = mock_instance(WASM, &[]);
-    let init_msg = InitMsg {
-        asset_chain: 1,
-        asset_address: vec![1; 32].into(),
-        decimals: 10,
-        mint: None,
-        init_hook: None,
-    };
-    let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
-    let res: InitResponse = init(&mut deps, env, init_msg).unwrap();
-    assert_eq!(0, res.messages.len());
-
-    // query the store directly
-    let api = deps.api;
-    deps.with_storage(|storage| {
-        assert_eq!(
-            get_wrapped_asset_info(storage),
-            WrappedAssetInfo {
-                asset_chain: 1,
-                asset_address: vec![1; 32].into(),
-                bridge: api.canonical_address(&TestAddress::INITIALIZER.value()).0?,
-            }
-        );
-        Ok(())
-    })
-    .unwrap();
-    deps
-}
-
-fn do_mint(
-    deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
-    height: u64,
-    recipient: &HumanAddr,
-    amount: &Uint128,
-) {
-    let mint_msg = HandleMsg::Mint {
-        recipient: recipient.clone(),
-        amount: amount.clone(),
-    };
-    let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
-    let handle_response: HandleResponse = handle(deps, env, mint_msg).unwrap();
-    assert_eq!(0, handle_response.messages.len());
-}
-
-fn do_transfer(
-    deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
-    height: u64,
-    sender: &HumanAddr,
-    recipient: &HumanAddr,
-    amount: &Uint128,
-) {
-    let transfer_msg = HandleMsg::Transfer {
-        recipient: recipient.clone(),
-        amount: amount.clone(),
-    };
-    let env = mock_env_height(sender, height, 0);
-    let handle_response: HandleResponse = handle(deps, env, transfer_msg).unwrap();
-    assert_eq!(0, handle_response.messages.len());
-}
-
-fn check_balance(
-    deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
-    address: &HumanAddr,
-    amount: &Uint128,
-) {
-    let query_response = query(
-        deps,
-        QueryMsg::Balance {
-            address: address.clone(),
-        },
-    )
-    .unwrap();
-    assert_eq!(
-        query_response.as_slice(),
-        format!("{{\"balance\":\"{}\"}}", amount.u128()).as_bytes()
-    );
-}
-
-fn check_token_details(deps: &mut Instance<MockStorage, MockApi, MockQuerier>, supply: &Uint128) {
-    let query_response = query(deps, QueryMsg::TokenInfo {}).unwrap();
-    assert_eq!(
-        query_response.as_slice(),
-        format!(
-            "{{\"name\":\"Wormhole Wrapped\",\
-        \"symbol\":\"WWT\",\
-        \"decimals\":10,\
-        \"total_supply\":\"{}\"}}",
-            supply.u128()
-        )
-        .as_bytes()
-    );
-}
-
-#[test]
-fn init_works() {
-    let mut deps = do_init(111);
-    check_token_details(&mut deps, &Uint128(0));
-}
-
-#[test]
-fn query_works() {
-    let mut deps = do_init(111);
-
-    let query_response = query(&mut deps, QueryMsg::WrappedAssetInfo {}).unwrap();
-    assert_eq!(
-        query_response.as_slice(),
-        format!(
-            "{{\"asset_chain\":1,\
-        \"asset_address\":\"{}\",\
-        \"bridge\":\"{}\"}}",
-            Binary::from(vec![1; 32]).to_base64(),
-            TestAddress::INITIALIZER.value().as_str()
-        )
-        .as_bytes()
-    );
-}
-
-#[test]
-fn mint_works() {
-    let mut deps = do_init(111);
-
-    do_mint(
-        &mut deps,
-        112,
-        &TestAddress::RECIPIENT.value(),
-        &Uint128(123_123_123),
-    );
-
-    check_balance(
-        &mut deps,
-        &TestAddress::RECIPIENT.value(),
-        &Uint128(123_123_123),
-    );
-    check_token_details(&mut deps, &Uint128(123_123_123));
-}
-
-#[test]
-fn others_cannot_mint() {
-    let mut deps = do_init(111);
-
-    let mint_msg = HandleMsg::Mint {
-        recipient: TestAddress::RECIPIENT.value(),
-        amount: Uint128(123_123_123),
-    };
-    let env = mock_env_height(&TestAddress::RECIPIENT.value(), 112, 0);
-    let handle_result: HandleResult<HandleResponse> = handle(&mut deps, env, mint_msg);
-    assert_eq!(
-        format!("{}", handle_result.unwrap_err()),
-        format!("{}", ContractError::Unauthorized {})
-    );
-}
-
-#[test]
-fn transfer_works() {
-    let mut deps = do_init(111);
-
-    do_mint(
-        &mut deps,
-        112,
-        &TestAddress::SENDER.value(),
-        &Uint128(123_123_123),
-    );
-    do_transfer(
-        &mut deps,
-        113,
-        &TestAddress::SENDER.value(),
-        &TestAddress::RECIPIENT.value(),
-        &Uint128(123_123_000),
-    );
-
-    check_balance(&mut deps, &TestAddress::SENDER.value(), &Uint128(123));
-    check_balance(
-        &mut deps,
-        &TestAddress::RECIPIENT.value(),
-        &Uint128(123_123_000),
-    );
-}

+ 0 - 5
terra/contracts-5/token-bridge/.cargo/config

@@ -1,5 +0,0 @@
-[alias]
-wasm = "build --release --target wasm32-unknown-unknown"
-wasm-debug = "build --target wasm32-unknown-unknown"
-unit-test = "test --lib --features backtraces"
-integration-test = "test --test integration"

+ 0 - 36
terra/contracts-5/token-bridge/Cargo.toml

@@ -1,36 +0,0 @@
-[package]
-name = "token-bridge"
-version = "0.1.0"
-authors = ["Yuriy Savchenko <yuriy.savchenko@gmail.com>"]
-edition = "2018"
-description = "Wormhole token bridge"
-
-[lib]
-crate-type = ["cdylib", "rlib"]
-
-[features]
-backtraces = ["cosmwasm-std/backtraces"]
-# use library feature to disable all init/handle/query exports
-library = []
-
-[dependencies]
-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.8.0"
-cw20-base = { version = "0.8.0", features = ["library"] }
-cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] }
-terraswap = "2.4.0"
-wormhole = { path = "../wormhole", features = ["library"] }
-thiserror = { version = "1.0.20" }
-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"
-lazy_static = "1.4.0"
-bigint = "4"
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.16.0", default-features = false }
-serde_json = "1.0"

+ 0 - 733
terra/contracts-5/token-bridge/src/contract.rs

@@ -1,733 +0,0 @@
-use crate::msg::WrappedRegistryResponse;
-use cosmwasm_std::{
-    entry_point,
-    to_binary,
-    Binary,
-    CanonicalAddr,
-    Coin,
-    CosmosMsg,
-    Deps,
-    DepsMut,
-    Empty,
-    Env,
-    MessageInfo,
-    QueryRequest,
-    Response,
-    StdError,
-    StdResult,
-    Uint128,
-    WasmMsg,
-    WasmQuery,
-};
-
-use crate::{
-    msg::{
-        ExecuteMsg,
-        InstantiateMsg,
-        QueryMsg,
-    },
-    state::{
-        bridge_contracts,
-        bridge_contracts_read,
-        config,
-        config_read,
-        receive_native,
-        send_native,
-        wrapped_asset,
-        wrapped_asset_address,
-        wrapped_asset_address_read,
-        wrapped_asset_read,
-        Action,
-        AssetMeta,
-        ConfigInfo,
-        RegisterChain,
-        TokenBridgeMessage,
-        TransferInfo,
-    },
-};
-use wormhole::{
-    byte_utils::{
-        extend_address_to_32,
-        extend_string_to_32,
-        get_string_from_32,
-        ByteUtils,
-    },
-    error::ContractError,
-};
-
-use cw20_base::msg::{
-    ExecuteMsg as TokenMsg,
-    QueryMsg as TokenQuery,
-};
-
-use wormhole::msg::{
-    ExecuteMsg as WormholeExecuteMsg,
-    QueryMsg as WormholeQueryMsg,
-};
-
-use wormhole::state::{
-    vaa_archive_add,
-    vaa_archive_check,
-    GovernancePacket,
-    ParsedVAA,
-};
-
-use cw20::TokenInfoResponse;
-
-use cw20_wrapped::msg::{
-    ExecuteMsg as WrappedMsg,
-    InitHook,
-    InstantiateMsg as WrappedInit,
-    QueryMsg as WrappedQuery,
-    WrappedAssetInfoResponse,
-};
-use terraswap::asset::{
-    Asset,
-    AssetInfo,
-};
-
-use sha3::{
-    Digest,
-    Keccak256,
-};
-use std::cmp::{
-    max,
-    min,
-};
-
-type HumanAddr = String;
-
-// Chain ID of Terra
-const CHAIN_ID: u16 = 3;
-
-const WRAPPED_ASSET_UPDATING: &str = "updating";
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn instantiate(
-    deps: DepsMut,
-    _env: Env,
-    _info: MessageInfo,
-    msg: InstantiateMsg,
-) -> StdResult<Response> {
-    // Save general wormhole info
-    let state = ConfigInfo {
-        gov_chain: msg.gov_chain,
-        gov_address: msg.gov_address.as_slice().to_vec(),
-        wormhole_contract: msg.wormhole_contract,
-        wrapped_asset_code_id: msg.wrapped_asset_code_id,
-    };
-    config(deps.storage).save(&state)?;
-
-    Ok(Response::default())
-}
-
-pub fn coins_after_tax(deps: DepsMut, coins: Vec<Coin>) -> StdResult<Vec<Coin>> {
-    let mut res = vec![];
-    for coin in coins {
-        let asset = Asset {
-            amount: coin.amount.clone(),
-            info: AssetInfo::NativeToken {
-                denom: coin.denom.clone(),
-            },
-        };
-        res.push(asset.deduct_tax(&deps.querier)?);
-    }
-    Ok(res)
-}
-
-pub fn parse_vaa(deps: DepsMut, block_time: u64, data: &Binary) -> StdResult<ParsedVAA> {
-    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 {
-            vaa: data.clone(),
-            block_time,
-        })?,
-    }))?;
-    Ok(vaa)
-}
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> {
-    match msg {
-        ExecuteMsg::RegisterAssetHook { asset_id } => {
-            handle_register_asset(deps, env, info, &asset_id.as_slice())
-        }
-        ExecuteMsg::InitiateTransfer {
-            asset,
-            amount,
-            recipient_chain,
-            recipient,
-            fee,
-            nonce,
-        } => handle_initiate_transfer(
-            deps,
-            env,
-            info,
-            asset,
-            amount,
-            recipient_chain,
-            recipient.as_slice().to_vec(),
-            fee,
-            nonce,
-        ),
-        ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data),
-        ExecuteMsg::CreateAssetMeta {
-            asset_address,
-            nonce,
-        } => handle_create_asset_meta(deps, env, info, &asset_address, nonce),
-    }
-}
-
-/// Handle wrapped asset registration messages
-fn handle_register_asset(
-    deps: DepsMut,
-    _env: Env,
-    info: MessageInfo,
-    asset_id: &[u8],
-) -> StdResult<Response> {
-    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, &info.sender.to_string())?;
-
-    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(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: DepsMut,
-    env: Env,
-    emitter_chain: u16,
-    emitter_address: Vec<u8>,
-    data: &Vec<u8>,
-) -> StdResult<Response> {
-    let meta = AssetMeta::deserialize(data)?;
-
-    let expected_contract =
-        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::generic_err("invalid emitter"));
-    }
-
-    if CHAIN_ID == meta.token_chain {
-        return Err(StdError::generic_err(
-            "this asset is native to this chain and should not be attested",
-        ));
-    }
-
-    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(deps.storage).load(&asset_id).is_ok() {
-        return Err(StdError::generic_err(
-            "this asset has already been attested",
-        ));
-    }
-
-    wrapped_asset(deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?;
-
-    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)?,
-                symbol: get_string_from_32(&meta.symbol)?,
-                asset_chain: meta.token_chain,
-                asset_address: meta.token_address.to_vec().into(),
-                decimals: min(meta.decimals, 8u8),
-                mint: None,
-                init_hook: Some(InitHook {
-                    contract_addr: env.contract.address.to_string(),
-                    msg: to_binary(&ExecuteMsg::RegisterAssetHook {
-                        asset_id: asset_id.to_vec().into(),
-                    })?,
-                }),
-            })?,
-            funds: vec![],
-            label: String::new(),
-        })),
-    )
-}
-
-fn handle_create_asset_meta(
-    deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    asset_address: &HumanAddr,
-    nonce: u32,
-) -> StdResult<Response> {
-    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.addr_canonicalize(asset_address)?;
-    let token_info: TokenInfoResponse = deps.querier.query(&request)?;
-
-    let meta: AssetMeta = AssetMeta {
-        token_chain: CHAIN_ID,
-        token_address: extend_address_to_32(&asset_canonical),
-        decimals: token_info.decimals,
-        symbol: extend_string_to_32(&token_info.symbol)?,
-        name: extend_string_to_32(&token_info.name)?,
-    };
-
-    let token_bridge_message = TokenBridgeMessage {
-        action: Action::ATTEST_META,
-        payload: meta.serialize().to_vec(),
-    };
-
-    Ok(Response::new()
-        .add_message(CosmosMsg::Wasm(WasmMsg::Execute {
-            contract_addr: cfg.wormhole_contract,
-            msg: to_binary(&WormholeExecuteMsg::PostMessage {
-                message: Binary::from(token_bridge_message.serialize()),
-                nonce,
-            })?,
-            // forward coins sent to this message
-            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(
-    mut deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    data: &Binary,
-) -> StdResult<Response> {
-    let state = config_read(deps.storage).load()?;
-
-    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()) {
-        return ContractError::VaaAlreadyExecuted.std_err();
-    }
-    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 {
-        return handle_governance_payload(deps, env, &data);
-    }
-
-    let message = TokenBridgeMessage::deserialize(&data)?;
-
-    match message.action {
-        Action::TRANSFER => handle_complete_transfer(
-            deps,
-            env,
-            info,
-            vaa.emitter_chain,
-            vaa.emitter_address,
-            &message.payload,
-        ),
-        Action::ATTEST_META => handle_attest_meta(
-            deps,
-            env,
-            vaa.emitter_chain,
-            vaa.emitter_address,
-            &message.payload,
-        ),
-        _ => ContractError::InvalidVAAAction.std_err(),
-    }
-}
-
-fn handle_governance_payload(deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    let gov_packet = GovernancePacket::deserialize(&data)?;
-    let module = get_string_from_32(&gov_packet.module)?;
-
-    if module != "TokenBridge" {
-        return Err(StdError::generic_err("this is not a valid module"));
-    }
-
-    if gov_packet.chain != 0 && gov_packet.chain != CHAIN_ID {
-        return Err(StdError::generic_err(
-            "the governance VAA is for another chain",
-        ));
-    }
-
-    match gov_packet.action {
-        1u8 => handle_register_chain(deps, env, &gov_packet.payload),
-        _ => ContractError::InvalidVAAAction.std_err(),
-    }
-}
-
-fn handle_register_chain(deps: DepsMut, _env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    let RegisterChain {
-        chain_id,
-        chain_address,
-    } = RegisterChain::deserialize(&data)?;
-
-    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(deps.storage);
-    bucket.save(&chain_id.to_be_bytes(), &chain_address)?;
-
-    Ok(Response::new()
-        .add_attribute("chain_id", chain_id.to_string())
-        .add_attribute("chain_address", hex::encode(chain_address)))
-}
-
-fn handle_complete_transfer(
-    deps: DepsMut,
-    _env: Env,
-    info: MessageInfo,
-    emitter_chain: u16,
-    emitter_address: Vec<u8>,
-    data: &Vec<u8>,
-) -> StdResult<Response> {
-    let transfer_info = TransferInfo::deserialize(&data)?;
-
-    let expected_contract =
-        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::generic_err("invalid emitter"));
-    }
-
-    if transfer_info.recipient_chain != CHAIN_ID {
-        return Err(StdError::generic_err(
-            "this transfer is not directed at this chain",
-        ));
-    }
-
-    let token_chain = transfer_info.token_chain;
-    let target_address = (&transfer_info.recipient.as_slice()).get_address(0);
-
-    let (not_supported_amount, mut amount) = transfer_info.amount;
-    let (not_supported_fee, mut fee) = transfer_info.fee;
-
-    amount = amount.checked_sub(fee).unwrap();
-
-    // Check high 128 bit of amount value to be empty
-    if not_supported_amount != 0 || not_supported_fee != 0 {
-        return ContractError::AmountTooHigh.std_err();
-    }
-
-    if token_chain != CHAIN_ID {
-        let asset_address = transfer_info.token_address;
-        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();
-
-        return if let Some(contract_addr) = contract_addr {
-            // Asset already deployed, just mint
-
-            let recipient = deps
-                .api
-                .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.to_string(),
-                    amount: Uint128::from(amount),
-                })?,
-                funds: vec![],
-            })];
-            if fee != 0 {
-                messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
-                    contract_addr: contract_addr.clone(),
-                    msg: to_binary(&WrappedMsg::Mint {
-                        recipient: info.sender.to_string(),
-                        amount: Uint128::from(fee),
-                    })?,
-                    funds: vec![],
-                }))
-            }
-
-            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.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(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.to_string(),
-                msg: to_binary(&TokenQuery::TokenInfo {})?,
-            }))?;
-
-        let decimals = token_info.decimals;
-        let multiplier = 10u128.pow((max(decimals, 8u8) - 8u8) as u32);
-        amount = amount.checked_mul(multiplier).unwrap();
-        fee = fee.checked_mul(multiplier).unwrap();
-
-        let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
-            contract_addr: contract_addr.to_string(),
-            msg: to_binary(&TokenMsg::Transfer {
-                recipient: recipient.to_string(),
-                amount: Uint128::from(amount),
-            })?,
-            funds: vec![],
-        })];
-
-        if fee != 0 {
-            messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
-                contract_addr: contract_addr.to_string(),
-                msg: to_binary(&TokenMsg::Transfer {
-                    recipient: info.sender.to_string(),
-                    amount: Uint128::from(fee),
-                })?,
-                funds: vec![],
-            }))
-        }
-
-        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(
-    mut deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    asset: HumanAddr,
-    mut amount: Uint128,
-    recipient_chain: u16,
-    recipient: Vec<u8>,
-    mut fee: Uint128,
-    nonce: u32,
-) -> StdResult<Response> {
-    if recipient_chain == CHAIN_ID {
-        return ContractError::SameSourceAndTarget.std_err();
-    }
-
-    if amount.is_zero() {
-        return ContractError::AmountTooLow.std_err();
-    }
-
-    if fee > amount {
-        return Err(StdError::generic_err("fee greater than sent amount"));
-    }
-
-    let asset_chain: u16;
-    let asset_address: Vec<u8>;
-
-    let cfg: ConfigInfo = config_read(deps.storage).load()?;
-    let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?;
-
-    let mut messages: Vec<CosmosMsg> = vec![];
-
-    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: info.sender.to_string(),
-                    amount,
-                })?,
-                funds: vec![],
-            }));
-            let request = QueryRequest::<Empty>::Wasm(WasmQuery::Smart {
-                contract_addr: asset,
-                msg: to_binary(&WrappedQuery::WrappedAssetInfo {})?,
-            });
-            let wrapped_token_info: WrappedAssetInfoResponse =
-                deps.querier.custom_query(&request)?;
-            asset_chain = wrapped_token_info.asset_chain;
-            asset_address = wrapped_token_info.asset_address.as_slice().to_vec();
-        }
-        Err(_) => {
-            // normalize amount to 8 decimals when it sent over the wormhole
-            let token_info: TokenInfoResponse =
-                deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
-                    contract_addr: asset.clone(),
-                    msg: to_binary(&TokenQuery::TokenInfo {})?,
-                }))?;
-
-            let decimals = token_info.decimals;
-            let multiplier = 10u128.pow((max(decimals, 8u8) - 8u8) as u32);
-            // chop off dust
-            amount = Uint128::new(
-                amount
-                    .u128()
-                    .checked_sub(amount.u128().checked_rem(multiplier).unwrap())
-                    .unwrap(),
-            );
-            fee = Uint128::new(
-                fee.u128()
-                    .checked_sub(fee.u128().checked_rem(multiplier).unwrap())
-                    .unwrap(),
-            );
-
-            // This is a regular asset, transfer its balance
-            messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
-                contract_addr: asset,
-                msg: to_binary(&TokenMsg::TransferFrom {
-                    owner: info.sender.to_string(),
-                    recipient: env.contract.address.to_string(),
-                    amount,
-                })?,
-                funds: vec![],
-            }));
-            asset_address = extend_address_to_32(&asset_canonical);
-            asset_chain = CHAIN_ID;
-
-            // convert to normalized amounts before recording & posting vaa
-            amount = Uint128::new(amount.u128().checked_div(multiplier).unwrap());
-            fee = Uint128::new(fee.u128().checked_div(multiplier).unwrap());
-
-            send_native(deps.storage, &asset_canonical, amount)?;
-        }
-    };
-
-    let transfer_info = TransferInfo {
-        token_chain: asset_chain,
-        token_address: asset_address.clone(),
-        amount: (0, amount.u128()),
-        recipient_chain,
-        recipient: recipient.clone(),
-        fee: (0, fee.u128()),
-    };
-
-    let token_bridge_message = TokenBridgeMessage {
-        action: Action::TRANSFER,
-        payload: transfer_info.serialize(),
-    };
-
-    messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
-        contract_addr: cfg.wormhole_contract,
-        msg: to_binary(&WormholeExecuteMsg::PostMessage {
-            message: Binary::from(token_bridge_message.serialize()),
-            nonce,
-        })?,
-        // forward coins sent to this message
-        funds: coins_after_tax(deps.branch(), info.funds.clone())?,
-    }));
-
-    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: Deps, msg: QueryMsg) -> StdResult<Binary> {
-    match msg {
-        QueryMsg::WrappedRegistry { chain, address } => {
-            to_binary(&query_wrapped_registry(deps, chain, address.as_slice())?)
-        }
-    }
-}
-
-pub fn query_wrapped_registry(
-    deps: Deps,
-    chain: u16,
-    address: &[u8],
-) -> StdResult<WrappedRegistryResponse> {
-    let asset_id = build_asset_id(chain, address);
-    // Check if this asset is already deployed
-    match wrapped_asset_read(deps.storage).load(&asset_id) {
-        Ok(address) => Ok(WrappedRegistryResponse { address }),
-        Err(_) => ContractError::AssetNotFound.std_err(),
-    }
-}
-
-fn build_asset_id(chain: u16, address: &[u8]) -> Vec<u8> {
-    let mut asset_id: Vec<u8> = vec![];
-    asset_id.extend_from_slice(&chain.to_be_bytes());
-    asset_id.extend_from_slice(address);
-
-    let mut hasher = Keccak256::new();
-    hasher.update(asset_id);
-    hasher.finalize().to_vec()
-}
-
-#[cfg(test)]
-mod tests {
-    use cosmwasm_std::{
-        to_binary,
-        Binary,
-        StdResult,
-    };
-
-    #[test]
-    fn test_me() -> StdResult<()> {
-        let x = vec![
-            1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 96u8, 180u8, 94u8, 195u8, 0u8, 0u8,
-            0u8, 1u8, 0u8, 3u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 38u8,
-            229u8, 4u8, 215u8, 149u8, 163u8, 42u8, 54u8, 156u8, 236u8, 173u8, 168u8, 72u8, 220u8,
-            100u8, 90u8, 154u8, 159u8, 160u8, 215u8, 0u8, 91u8, 48u8, 44u8, 48u8, 44u8, 51u8, 44u8,
-            48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8,
-            48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 55u8, 44u8, 52u8,
-            54u8, 44u8, 50u8, 53u8, 53u8, 44u8, 53u8, 48u8, 44u8, 50u8, 52u8, 51u8, 44u8, 49u8,
-            48u8, 54u8, 44u8, 49u8, 50u8, 50u8, 44u8, 49u8, 49u8, 48u8, 44u8, 49u8, 50u8, 53u8,
-            44u8, 56u8, 56u8, 44u8, 55u8, 51u8, 44u8, 49u8, 56u8, 57u8, 44u8, 50u8, 48u8, 55u8,
-            44u8, 49u8, 48u8, 52u8, 44u8, 56u8, 51u8, 44u8, 49u8, 49u8, 57u8, 44u8, 49u8, 50u8,
-            55u8, 44u8, 49u8, 57u8, 50u8, 44u8, 49u8, 52u8, 55u8, 44u8, 56u8, 57u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 51u8, 44u8, 50u8, 51u8, 50u8, 44u8, 48u8, 44u8, 51u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
-            44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 51u8, 44u8, 49u8, 49u8,
-            54u8, 44u8, 52u8, 56u8, 44u8, 49u8, 49u8, 54u8, 44u8, 49u8, 52u8, 57u8, 44u8, 49u8,
-            48u8, 56u8, 44u8, 49u8, 49u8, 51u8, 44u8, 56u8, 44u8, 48u8, 44u8, 50u8, 51u8, 50u8,
-            44u8, 52u8, 57u8, 44u8, 49u8, 53u8, 50u8, 44u8, 49u8, 44u8, 50u8, 56u8, 44u8, 50u8,
-            48u8, 51u8, 44u8, 50u8, 49u8, 50u8, 44u8, 50u8, 50u8, 49u8, 44u8, 50u8, 52u8, 49u8,
-            44u8, 56u8, 53u8, 44u8, 49u8, 48u8, 57u8, 93u8,
-        ];
-        let b = Binary::from(x.clone());
-        let y = b.as_slice().to_vec();
-        assert_eq!(x, y);
-        Ok(())
-    }
-}

+ 0 - 10
terra/contracts-5/token-bridge/src/lib.rs

@@ -1,10 +0,0 @@
-#[cfg(test)]
-#[macro_use]
-extern crate lazy_static;
-
-pub mod contract;
-pub mod msg;
-pub mod state;
-
-#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
-cosmwasm_std::create_entry_points!(contract);

+ 0 - 71
terra/contracts-5/token-bridge/src/msg.rs

@@ -1,71 +0,0 @@
-use cosmwasm_std::{
-    Binary,
-    Uint128,
-};
-use terraswap::asset::{Asset, AssetInfo};
-use schemars::JsonSchema;
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-type HumanAddr = String;
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InstantiateMsg {
-    // governance contract details
-    pub gov_chain: u16,
-    pub gov_address: Binary,
-
-    pub wormhole_contract: HumanAddr,
-    pub wrapped_asset_code_id: u64,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum ExecuteMsg {
-    RegisterAssetHook {
-        asset_id: Binary,
-    },
-
-    DepositTokens {},
-    WithdrawTokens {
-        asset: AssetInfo,
-    },
-
-
-    InitiateTransfer {
-        asset: Asset,
-        recipient_chain: u16,
-        recipient: Binary,
-        fee: Uint128,
-        nonce: u32,
-    },
-
-    SubmitVaa {
-        data: Binary,
-    },
-
-    CreateAssetMeta {
-        asset_info: AssetInfo,
-        nonce: u32,
-    },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum QueryMsg {
-    WrappedRegistry { chain: u16, address: Binary },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct WrappedRegistryResponse {
-    pub address: HumanAddr,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum WormholeQueryMsg {
-    VerifyVAA { vaa: Binary, block_time: u64 },
-}

+ 0 - 249
terra/contracts-5/token-bridge/src/state.rs

@@ -1,249 +0,0 @@
-use schemars::JsonSchema;
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-use cosmwasm_std::{
-    CanonicalAddr,
-    StdError,
-    StdResult,
-    Storage,
-    Uint128,
-};
-use cosmwasm_storage::{
-    bucket,
-    bucket_read,
-    singleton,
-    singleton_read,
-    Bucket,
-    ReadonlyBucket,
-    ReadonlySingleton,
-    Singleton,
-};
-
-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";
-pub static BRIDGE_CONTRACTS: &[u8] = b"bridge_contracts";
-pub static NATIVE_COUNTER: &[u8] = b"native_counter";
-
-// Guardian set information
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct ConfigInfo {
-    // governance contract details
-    pub gov_chain: u16,
-    pub gov_address: Vec<u8>,
-
-    pub wormhole_contract: HumanAddr,
-    pub wrapped_asset_code_id: u64,
-}
-
-pub fn config(storage: &mut dyn Storage) -> Singleton<ConfigInfo> {
-    singleton(storage, CONFIG_KEY)
-}
-
-pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton<ConfigInfo> {
-    singleton_read(storage, CONFIG_KEY)
-}
-
-pub fn bridge_contracts(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
-    bucket(storage, BRIDGE_CONTRACTS)
-}
-
-pub fn bridge_contracts_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
-    bucket_read(storage, BRIDGE_CONTRACTS)
-}
-
-pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket<HumanAddr> {
-    bucket(storage, WRAPPED_ASSET_KEY)
-}
-
-pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<HumanAddr> {
-    bucket_read(storage, WRAPPED_ASSET_KEY)
-}
-
-pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
-    bucket(storage, WRAPPED_ASSET_ADDRESS_KEY)
-}
-
-pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
-    bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY)
-}
-
-pub fn send_native(
-    storage: &mut dyn Storage,
-    asset_address: &CanonicalAddr,
-    amount: Uint128,
-) -> StdResult<()> {
-    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::new(u64::MAX as u128) {
-        return Err(StdError::generic_err(
-            "transfer exceeds max outstanding bridged token amount",
-        ));
-    }
-    counter_bucket.save(asset_address.as_slice(), &new_total)
-}
-
-pub fn receive_native(
-    storage: &mut dyn Storage,
-    asset_address: &CanonicalAddr,
-    amount: Uint128,
-) -> StdResult<()> {
-    let mut counter_bucket = bucket(storage, NATIVE_COUNTER);
-    let total: Uint128 = counter_bucket.load(asset_address.as_slice())?;
-    let result = total.checked_sub(amount)?;
-    counter_bucket.save(asset_address.as_slice(), &result)
-}
-
-pub struct Action;
-
-impl Action {
-    pub const TRANSFER: u8 = 1;
-    pub const ATTEST_META: u8 = 2;
-}
-
-// 0 u8 action
-// 1 [u8] payload
-
-pub struct TokenBridgeMessage {
-    pub action: u8,
-    pub payload: Vec<u8>,
-}
-
-impl TokenBridgeMessage {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let action = data.get_u8(0);
-        let payload = &data[1..];
-
-        Ok(TokenBridgeMessage {
-            action,
-            payload: payload.to_vec(),
-        })
-    }
-
-    pub fn serialize(&self) -> Vec<u8> {
-        [self.action.to_be_bytes().to_vec(), self.payload.clone()].concat()
-    }
-}
-
-//     0   u256     amount
-//     32  [u8; 32] token_address
-//     64  u16      token_chain
-//     66  [u8; 32] recipient
-//     98  u16      recipient_chain
-//     100 u256     fee
-
-pub struct TransferInfo {
-    pub amount: (u128, u128),
-    pub token_address: Vec<u8>,
-    pub token_chain: u16,
-    pub recipient: Vec<u8>,
-    pub recipient_chain: u16,
-    pub fee: (u128, u128),
-}
-
-impl TransferInfo {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let amount = data.get_u256(0);
-        let token_address = data.get_bytes32(32).to_vec();
-        let token_chain = data.get_u16(64);
-        let recipient = data.get_bytes32(66).to_vec();
-        let recipient_chain = data.get_u16(98);
-        let fee = data.get_u256(100);
-
-        Ok(TransferInfo {
-            amount,
-            token_address,
-            token_chain,
-            recipient,
-            recipient_chain,
-            fee,
-        })
-    }
-    pub fn serialize(&self) -> Vec<u8> {
-        [
-            self.amount.0.to_be_bytes().to_vec(),
-            self.amount.1.to_be_bytes().to_vec(),
-            self.token_address.clone(),
-            self.token_chain.to_be_bytes().to_vec(),
-            self.recipient.to_vec(),
-            self.recipient_chain.to_be_bytes().to_vec(),
-            self.fee.0.to_be_bytes().to_vec(),
-            self.fee.1.to_be_bytes().to_vec(),
-        ]
-        .concat()
-    }
-}
-
-// 0  [32]uint8  TokenAddress
-// 32 uint16     TokenChain
-// 34 uint8      Decimals
-// 35 [32]uint8  Symbol
-// 67 [32]uint8  Name
-
-pub struct AssetMeta {
-    pub token_address: Vec<u8>,
-    pub token_chain: u16,
-    pub decimals: u8,
-    pub symbol: Vec<u8>,
-    pub name: Vec<u8>,
-}
-
-impl AssetMeta {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let token_address = data.get_bytes32(0).to_vec();
-        let token_chain = data.get_u16(32);
-        let decimals = data.get_u8(34);
-        let symbol = data.get_bytes32(35).to_vec();
-        let name = data.get_bytes32(67).to_vec();
-
-        Ok(AssetMeta {
-            token_chain,
-            token_address,
-            decimals,
-            symbol,
-            name,
-        })
-    }
-
-    pub fn serialize(&self) -> Vec<u8> {
-        [
-            self.token_address.clone(),
-            self.token_chain.to_be_bytes().to_vec(),
-            self.decimals.to_be_bytes().to_vec(),
-            self.symbol.clone(),
-            self.name.clone(),
-        ]
-        .concat()
-    }
-}
-
-pub struct RegisterChain {
-    pub chain_id: u16,
-    pub chain_address: Vec<u8>,
-}
-
-impl RegisterChain {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let chain_id = data.get_u16(0);
-        let chain_address = data[2..].to_vec();
-
-        Ok(RegisterChain {
-            chain_id,
-            chain_address,
-        })
-    }
-}

+ 0 - 114
terra/contracts-5/token-bridge/tests/integration.rs

@@ -1,114 +0,0 @@
-static WASM: &[u8] = include_bytes!("../../../target/wasm32-unknown-unknown/release/wormhole.wasm");
-
-use cosmwasm_std::{
-    from_slice,
-    Coin,
-    Env,
-    HumanAddr,
-    InitResponse,
-};
-use cosmwasm_storage::to_length_prefixed;
-use cosmwasm_vm::{
-    testing::{
-        init,
-        mock_env,
-        mock_instance,
-        MockApi,
-        MockQuerier,
-        MockStorage,
-    },
-    Api,
-    Instance,
-    Storage,
-};
-
-use wormhole::{
-    msg::InitMsg,
-    state::{
-        ConfigInfo,
-        GuardianAddress,
-        GuardianSetInfo,
-        CONFIG_KEY,
-    },
-};
-
-use hex;
-
-enum TestAddress {
-    INITIALIZER,
-}
-
-impl TestAddress {
-    fn value(&self) -> HumanAddr {
-        match self {
-            TestAddress::INITIALIZER => HumanAddr::from("initializer"),
-        }
-    }
-}
-
-fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env {
-    let mut env = mock_env(signer, &[]);
-    env.block.height = height;
-    env.block.time = time;
-    env
-}
-
-fn get_config_info<S: Storage>(storage: &S) -> ConfigInfo {
-    let key = to_length_prefixed(CONFIG_KEY);
-    let data = storage
-        .get(&key)
-        .0
-        .expect("error getting data")
-        .expect("data should exist");
-    from_slice(&data).expect("invalid data")
-}
-
-fn do_init(
-    height: u64,
-    guardians: &Vec<GuardianAddress>,
-) -> Instance<MockStorage, MockApi, MockQuerier> {
-    let mut deps = mock_instance(WASM, &[]);
-    let init_msg = InitMsg {
-        initial_guardian_set: GuardianSetInfo {
-            addresses: guardians.clone(),
-            expiration_time: 100,
-        },
-        guardian_set_expirity: 50,
-        wrapped_asset_code_id: 999,
-    };
-    let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
-    let owner = deps
-        .api
-        .canonical_address(&TestAddress::INITIALIZER.value())
-        .0
-        .unwrap();
-    let res: InitResponse = init(&mut deps, env, init_msg).unwrap();
-    assert_eq!(0, res.messages.len());
-
-    // query the store directly
-    deps.with_storage(|storage| {
-        assert_eq!(
-            get_config_info(storage),
-            ConfigInfo {
-                guardian_set_index: 0,
-                guardian_set_expirity: 50,
-                wrapped_asset_code_id: 999,
-                owner,
-                fee: Coin::new(10000, "uluna"),
-            }
-        );
-        Ok(())
-    })
-    .unwrap();
-    deps
-}
-
-#[test]
-fn init_works() {
-    let guardians = vec![GuardianAddress::from(GuardianAddress {
-        bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe")
-            .expect("Decoding failed")
-            .into(),
-    })];
-    let _deps = do_init(111, &guardians);
-}

+ 0 - 5
terra/contracts-5/wormhole/.cargo/config

@@ -1,5 +0,0 @@
-[alias]
-wasm = "build --release --target wasm32-unknown-unknown"
-wasm-debug = "build --target wasm32-unknown-unknown"
-unit-test = "test --lib --features backtraces"
-integration-test = "test --test integration"

+ 0 - 33
terra/contracts-5/wormhole/Cargo.toml

@@ -1,33 +0,0 @@
-[package]
-name = "wormhole"
-version = "0.1.0"
-authors = ["Yuriy Savchenko <yuriy.savchenko@gmail.com>"]
-edition = "2018"
-description = "Wormhole contract"
-
-[lib]
-crate-type = ["cdylib", "rlib"]
-
-[features]
-backtraces = ["cosmwasm-std/backtraces"]
-# use library feature to disable all init/handle/query exports
-library = []
-
-[dependencies]
-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.8.0"
-cw20-base = { version = "0.8.0", features = ["library"] }
-cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] }
-thiserror = { version = "1.0.20" }
-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"
-lazy_static = "1.4.0"
-
-[dev-dependencies]
-cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] }
-serde_json = "1.0"

+ 0 - 76
terra/contracts-5/wormhole/src/byte_utils.rs

@@ -1,76 +0,0 @@
-use cosmwasm_std::{
-    CanonicalAddr,
-    StdError,
-    StdResult,
-};
-
-pub trait ByteUtils {
-    fn get_u8(&self, index: usize) -> u8;
-    fn get_u16(&self, index: usize) -> u16;
-    fn get_u32(&self, index: usize) -> u32;
-    fn get_u64(&self, index: usize) -> u64;
-
-    fn get_u128_be(&self, index: usize) -> u128;
-    /// High 128 then low 128
-    fn get_u256(&self, index: usize) -> (u128, u128);
-    fn get_address(&self, index: usize) -> CanonicalAddr;
-    fn get_bytes32(&self, index: usize) -> &[u8];
-}
-
-impl ByteUtils for &[u8] {
-    fn get_u8(&self, index: usize) -> u8 {
-        self[index]
-    }
-    fn get_u16(&self, index: usize) -> u16 {
-        let mut bytes: [u8; 16 / 8] = [0; 16 / 8];
-        bytes.copy_from_slice(&self[index..index + 2]);
-        u16::from_be_bytes(bytes)
-    }
-    fn get_u32(&self, index: usize) -> u32 {
-        let mut bytes: [u8; 32 / 8] = [0; 32 / 8];
-        bytes.copy_from_slice(&self[index..index + 4]);
-        u32::from_be_bytes(bytes)
-    }
-    fn get_u64(&self, index: usize) -> u64 {
-        let mut bytes: [u8; 64 / 8] = [0; 64 / 8];
-        bytes.copy_from_slice(&self[index..index + 8]);
-        u64::from_be_bytes(bytes)
-    }
-    fn get_u128_be(&self, index: usize) -> u128 {
-        let mut bytes: [u8; 128 / 8] = [0; 128 / 8];
-        bytes.copy_from_slice(&self[index..index + 128 / 8]);
-        u128::from_be_bytes(bytes)
-    }
-    fn get_u256(&self, index: usize) -> (u128, u128) {
-        (self.get_u128_be(index), self.get_u128_be(index + 128 / 8))
-    }
-    fn get_address(&self, index: usize) -> CanonicalAddr {
-        // 32 bytes are reserved for addresses, but only the last 20 bytes are taken by the actual address
-        CanonicalAddr::from(&self[index + 32 - 20..index + 32])
-    }
-    fn get_bytes32(&self, index: usize) -> &[u8] {
-        &self[index..index + 32]
-    }
-}
-
-pub fn extend_address_to_32(addr: &CanonicalAddr) -> Vec<u8> {
-    let mut result: Vec<u8> = vec![0; 12];
-    result.extend(addr.as_slice());
-    result
-}
-
-pub fn extend_string_to_32(s: &String) -> StdResult<Vec<u8>> {
-    let bytes = s.as_bytes();
-    if bytes.len() > 32 {
-        return Err(StdError::generic_err("string more than 32 "));
-    }
-
-    let result = vec![0; 32 - bytes.len()];
-    Ok([bytes.to_vec(), result].concat())
-}
-
-pub fn get_string_from_32(v: &Vec<u8>) -> StdResult<String> {
-    let s = String::from_utf8(v.clone())
-        .or_else(|_| Err(StdError::generic_err("could not parse string")))?;
-    Ok(s.chars().filter(|c| c != &'\0').collect())
-}

+ 0 - 387
terra/contracts-5/wormhole/src/contract.rs

@@ -1,387 +0,0 @@
-use cosmwasm_std::{
-    entry_point,
-    has_coins,
-    to_binary,
-    BankMsg,
-    Binary,
-    Coin,
-    CosmosMsg,
-    Deps,
-    DepsMut,
-    Env,
-    MessageInfo,
-    Response,
-    StdError,
-    StdResult,
-    Storage,
-};
-
-use crate::{
-    byte_utils::{
-        extend_address_to_32,
-        ByteUtils,
-    },
-    error::ContractError,
-    msg::{
-        ExecuteMsg,
-        GetAddressHexResponse,
-        GetStateResponse,
-        GuardianSetInfoResponse,
-        InstantiateMsg,
-        QueryMsg,
-    },
-    state::{
-        config,
-        config_read,
-        guardian_set_get,
-        guardian_set_set,
-        sequence_read,
-        sequence_set,
-        vaa_archive_add,
-        vaa_archive_check,
-        ConfigInfo,
-        GovernancePacket,
-        GuardianAddress,
-        GuardianSetInfo,
-        GuardianSetUpgrade,
-        ParsedVAA,
-        SetFee,
-        TransferFee,
-    },
-};
-
-use k256::{
-    ecdsa::{
-        recoverable::{
-            Id as RecoverableId,
-            Signature as RecoverableSignature,
-        },
-        Signature,
-        VerifyingKey,
-    },
-    EncodedPoint,
-};
-use sha3::{
-    Digest,
-    Keccak256,
-};
-
-use generic_array::GenericArray;
-use std::convert::TryFrom;
-
-type HumanAddr = String;
-
-// Chain ID of Terra
-const CHAIN_ID: u16 = 3;
-
-// Lock assets fee amount and denomination
-const FEE_AMOUNT: u128 = 10000;
-pub const FEE_DENOMINATION: &str = "uluna";
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn instantiate(deps: DepsMut, _env: Env, msg: InstantiateMsg) -> StdResult<Response> {
-    // Save general wormhole info
-    let state = ConfigInfo {
-        gov_chain: msg.gov_chain,
-        gov_address: msg.gov_address.as_slice().to_vec(),
-        guardian_set_index: 0,
-        guardian_set_expirity: msg.guardian_set_expirity,
-        fee: Coin::new(FEE_AMOUNT, FEE_DENOMINATION), // 0.01 Luna (or 10000 uluna) fee by default
-    };
-    config(deps.storage).save(&state)?;
-
-    // Add initial guardian set to storage
-    guardian_set_set(
-        deps.storage,
-        state.guardian_set_index,
-        &msg.initial_guardian_set,
-    )?;
-
-    Ok(Response::default())
-}
-
-#[cfg_attr(not(feature = "library"), entry_point)]
-pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> {
-    match msg {
-        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()),
-    }
-}
-
-/// Process VAA message signed by quardians
-fn handle_submit_vaa(
-    deps: DepsMut,
-    env: Env,
-    _info: MessageInfo,
-    data: &[u8],
-) -> StdResult<Response> {
-    let state = config_read(deps.storage).load()?;
-
-    let vaa = parse_and_verify_vaa(deps.storage, data, env.block.time.seconds())?;
-    vaa_archive_add(deps.storage, vaa.hash.as_slice())?;
-
-    if state.gov_chain == vaa.emitter_chain && state.gov_address == vaa.emitter_address {
-        if state.guardian_set_index != vaa.guardian_set_index {
-            return Err(StdError::generic_err(
-                "governance VAAs must be signed by the current guardian set",
-            ));
-        }
-        return handle_governance_payload(deps, env, &vaa.payload);
-    }
-
-    ContractError::InvalidVAAAction.std_err()
-}
-
-fn handle_governance_payload(deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    let gov_packet = GovernancePacket::deserialize(&data)?;
-
-    let module = String::from_utf8(gov_packet.module).unwrap();
-    let module: String = module.chars().filter(|c| c != &'\0').collect();
-
-    if module != "Core" {
-        return Err(StdError::generic_err("this is not a valid module"));
-    }
-
-    if gov_packet.chain != 0 && gov_packet.chain != CHAIN_ID {
-        return Err(StdError::generic_err(
-            "the governance VAA is for another chain",
-        ));
-    }
-
-    match gov_packet.action {
-        // 1 is reserved for upgrade / migration
-        2u8 => vaa_update_guardian_set(deps, env, &gov_packet.payload),
-        3u8 => handle_set_fee(deps, env, &gov_packet.payload),
-        4u8 => handle_transfer_fee(deps, env, &gov_packet.payload),
-        _ => ContractError::InvalidVAAAction.std_err(),
-    }
-}
-
-/// Parses raw VAA data into a struct and verifies whether it contains sufficient signatures of an
-/// active guardian set i.e. is valid according to Wormhole consensus rules
-fn parse_and_verify_vaa(
-    storage: &dyn Storage,
-    data: &[u8],
-    block_time: u64,
-) -> StdResult<ParsedVAA> {
-    let vaa = ParsedVAA::deserialize(data)?;
-
-    if vaa.version != 1 {
-        return ContractError::InvalidVersion.std_err();
-    }
-
-    // Check if VAA with this hash was already accepted
-    if vaa_archive_check(storage, vaa.hash.as_slice()) {
-        return ContractError::VaaAlreadyExecuted.std_err();
-    }
-
-    // Load and check guardian set
-    let guardian_set = guardian_set_get(storage, vaa.guardian_set_index);
-    let guardian_set: GuardianSetInfo =
-        guardian_set.or_else(|_| ContractError::InvalidGuardianSetIndex.std_err())?;
-
-    if guardian_set.expiration_time != 0 && guardian_set.expiration_time < block_time {
-        return ContractError::GuardianSetExpired.std_err();
-    }
-    if (vaa.len_signers as usize) < guardian_set.quorum() {
-        return ContractError::NoQuorum.std_err();
-    }
-
-    // Verify guardian signatures
-    let mut last_index: i32 = -1;
-    let mut pos = ParsedVAA::HEADER_LEN;
-
-    for _ in 0..vaa.len_signers {
-        if pos + ParsedVAA::SIGNATURE_LEN > data.len() {
-            return ContractError::InvalidVAA.std_err();
-        }
-        let index = data.get_u8(pos) as i32;
-        if index <= last_index {
-            return ContractError::WrongGuardianIndexOrder.std_err();
-        }
-        last_index = index;
-
-        let signature = Signature::try_from(
-            &data[pos + ParsedVAA::SIG_DATA_POS
-                ..pos + ParsedVAA::SIG_DATA_POS + ParsedVAA::SIG_DATA_LEN],
-        )
-        .or_else(|_| ContractError::CannotDecodeSignature.std_err())?;
-        let id = RecoverableId::new(data.get_u8(pos + ParsedVAA::SIG_RECOVERY_POS))
-            .or_else(|_| ContractError::CannotDecodeSignature.std_err())?;
-        let recoverable_signature = RecoverableSignature::new(&signature, id)
-            .or_else(|_| ContractError::CannotDecodeSignature.std_err())?;
-
-        let verify_key = recoverable_signature
-            .recover_verify_key_from_digest_bytes(GenericArray::from_slice(vaa.hash.as_slice()))
-            .or_else(|_| ContractError::CannotRecoverKey.std_err())?;
-
-        let index = index as usize;
-        if index >= guardian_set.addresses.len() {
-            return ContractError::TooManySignatures.std_err();
-        }
-        if !keys_equal(&verify_key, &guardian_set.addresses[index]) {
-            return ContractError::GuardianSignatureError.std_err();
-        }
-        pos += ParsedVAA::SIGNATURE_LEN;
-    }
-
-    Ok(vaa)
-}
-
-fn vaa_update_guardian_set(deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    /* Payload format
-    0   uint32 new_index
-    4   uint8 len(keys)
-    5   [][20]uint8 guardian addresses
-    */
-
-    let mut state = config_read(deps.storage).load()?;
-
-    let GuardianSetUpgrade {
-        new_guardian_set_index,
-        new_guardian_set,
-    } = GuardianSetUpgrade::deserialize(&data)?;
-
-    if new_guardian_set_index != state.guardian_set_index + 1 {
-        return ContractError::GuardianSetIndexIncreaseError.std_err();
-    }
-
-    let old_guardian_set_index = state.guardian_set_index;
-
-    state.guardian_set_index = new_guardian_set_index;
-
-    guardian_set_set(deps.storage, state.guardian_set_index, &new_guardian_set)?;
-
-    config(deps.storage).save(&state)?;
-
-    let mut old_guardian_set = guardian_set_get(deps.storage, old_guardian_set_index)?;
-    old_guardian_set.expiration_time = env.block.time.seconds() + state.guardian_set_expirity;
-    guardian_set_set(deps.storage, old_guardian_set_index, &old_guardian_set)?;
-
-    Ok(Response::new()
-        .add_attribute("action", "guardian_set_change")
-        .add_attribute("old", old_guardian_set_index.to_string())
-        .add_attribute("new", state.guardian_set_index.to_string()))
-}
-
-pub fn handle_set_fee(deps: DepsMut, _env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    let set_fee_msg = SetFee::deserialize(&data)?;
-
-    // Save new fees
-    let mut state = config_read(deps.storage).load()?;
-    state.fee = set_fee_msg.fee;
-    config(deps.storage).save(&state)?;
-
-    Ok(Response::new()
-        .add_attribute("action", "fee_change")
-        .add_attribute("new_fee.amount", state.fee.amount.to_string())
-        .add_attribute("new_fee.denom", state.fee.denom.to_string()))
-}
-
-pub fn handle_transfer_fee(deps: DepsMut, _env: Env, data: &Vec<u8>) -> StdResult<Response> {
-    let transfer_msg = TransferFee::deserialize(&data)?;
-
-    Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send {
-        to_address: deps.api.addr_humanize(&transfer_msg.recipient)?.to_string(),
-        amount: vec![transfer_msg.amount],
-    })))
-}
-
-fn handle_post_message(
-    deps: DepsMut,
-    env: Env,
-    info: MessageInfo,
-    message: &[u8],
-    nonce: u32,
-) -> StdResult<Response> {
-    let state = config_read(deps.storage).load()?;
-    let fee = state.fee;
-
-    // Check fee
-    if !has_coins(info.funds.as_ref(), &fee) {
-        return ContractError::FeeTooLow.std_err();
-    }
-
-    let emitter = extend_address_to_32(&deps.api.addr_canonicalize(&info.sender.as_str())?);
-    let sequence = sequence_read(deps.storage, emitter.as_slice());
-    sequence_set(deps.storage, emitter.as_slice(), sequence + 1)?;
-
-    Ok(Response::new()
-        .add_attribute("message.message", hex::encode(message))
-        .add_attribute("message.sender", hex::encode(emitter))
-        .add_attribute("message.chain_id", CHAIN_ID.to_string())
-        .add_attribute("message.nonce", nonce.to_string())
-        .add_attribute("message.sequence", sequence.to_string())
-        .add_attribute("message.block_time", env.block.time.seconds().to_string()))
-}
-
-pub fn query(deps: Deps, msg: QueryMsg) -> StdResult<Binary> {
-    match msg {
-        QueryMsg::GuardianSetInfo {} => to_binary(&query_guardian_set_info(deps)?),
-        QueryMsg::VerifyVAA { vaa, block_time } => to_binary(&query_parse_and_verify_vaa(
-            deps,
-            &vaa.as_slice(),
-            block_time,
-        )?),
-        QueryMsg::GetState {} => to_binary(&query_state(deps)?),
-        QueryMsg::QueryAddressHex { address } => to_binary(&query_address_hex(deps, &address)?),
-    }
-}
-
-pub fn query_guardian_set_info(deps: Deps) -> StdResult<GuardianSetInfoResponse> {
-    let state = config_read(deps.storage).load()?;
-    let guardian_set = guardian_set_get(deps.storage, state.guardian_set_index)?;
-    let res = GuardianSetInfoResponse {
-        guardian_set_index: state.guardian_set_index,
-        addresses: guardian_set.addresses,
-    };
-    Ok(res)
-}
-
-pub fn query_parse_and_verify_vaa(
-    deps: Deps,
-    data: &[u8],
-    block_time: u64,
-) -> StdResult<ParsedVAA> {
-    parse_and_verify_vaa(deps.storage, data, block_time)
-}
-
-// returns the hex of the 32 byte address we use for some address on this chain
-pub fn query_address_hex(deps: Deps, address: &HumanAddr) -> StdResult<GetAddressHexResponse> {
-    Ok(GetAddressHexResponse {
-        hex: hex::encode(extend_address_to_32(&deps.api.addr_canonicalize(&address)?)),
-    })
-}
-
-pub fn query_state(deps: Deps) -> StdResult<GetStateResponse> {
-    let state = config_read(deps.storage).load()?;
-    let res = GetStateResponse { fee: state.fee };
-    Ok(res)
-}
-
-fn keys_equal(a: &VerifyingKey, b: &GuardianAddress) -> bool {
-    let mut hasher = Keccak256::new();
-
-    let point: EncodedPoint = EncodedPoint::from(a);
-    let point = point.decompress();
-    if bool::from(point.is_none()) {
-        return false;
-    }
-    let point = point.unwrap();
-
-    hasher.update(&point.as_bytes()[1..]);
-    let a = &hasher.finalize()[12..];
-
-    let b = &b.bytes;
-    if a.len() != b.len() {
-        return false;
-    }
-    for (ai, bi) in a.iter().zip(b.as_slice().iter()) {
-        if ai != bi {
-            return false;
-        }
-    }
-    true
-}

+ 0 - 113
terra/contracts-5/wormhole/src/error.rs

@@ -1,113 +0,0 @@
-use cosmwasm_std::StdError;
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum ContractError {
-    /// Invalid VAA version
-    #[error("InvalidVersion")]
-    InvalidVersion,
-
-    /// Guardian set with this index does not exist
-    #[error("InvalidGuardianSetIndex")]
-    InvalidGuardianSetIndex,
-
-    /// Guardian set expiration date is zero or in the past
-    #[error("GuardianSetExpired")]
-    GuardianSetExpired,
-
-    /// Not enough signers on the VAA
-    #[error("NoQuorum")]
-    NoQuorum,
-
-    /// Wrong guardian index order, order must be ascending
-    #[error("WrongGuardianIndexOrder")]
-    WrongGuardianIndexOrder,
-
-    /// Some problem with signature decoding from bytes
-    #[error("CannotDecodeSignature")]
-    CannotDecodeSignature,
-
-    /// Some problem with public key recovery from the signature
-    #[error("CannotRecoverKey")]
-    CannotRecoverKey,
-
-    /// Recovered pubkey from signature does not match guardian address
-    #[error("GuardianSignatureError")]
-    GuardianSignatureError,
-
-    /// VAA action code not recognized
-    #[error("InvalidVAAAction")]
-    InvalidVAAAction,
-
-    /// VAA guardian set is not current
-    #[error("NotCurrentGuardianSet")]
-    NotCurrentGuardianSet,
-
-    /// Only 128-bit amounts are supported
-    #[error("AmountTooHigh")]
-    AmountTooHigh,
-
-    /// Amount should be higher than zero
-    #[error("AmountTooLow")]
-    AmountTooLow,
-
-    /// Source and target chain ids must be different
-    #[error("SameSourceAndTarget")]
-    SameSourceAndTarget,
-
-    /// Target chain id must be the same as the current CHAIN_ID
-    #[error("WrongTargetChain")]
-    WrongTargetChain,
-
-    /// Wrapped asset init hook sent twice for the same asset id
-    #[error("AssetAlreadyRegistered")]
-    AssetAlreadyRegistered,
-
-    /// Guardian set must increase in steps of 1
-    #[error("GuardianSetIndexIncreaseError")]
-    GuardianSetIndexIncreaseError,
-
-    /// VAA was already executed
-    #[error("VaaAlreadyExecuted")]
-    VaaAlreadyExecuted,
-
-    /// Message sender not permitted to execute this operation
-    #[error("PermissionDenied")]
-    PermissionDenied,
-
-    /// Could not decode target address from canonical to human-readable form
-    #[error("WrongTargetAddressFormat")]
-    WrongTargetAddressFormat,
-
-    /// More signatures than active guardians found
-    #[error("TooManySignatures")]
-    TooManySignatures,
-
-    /// Wrapped asset not found in the registry
-    #[error("AssetNotFound")]
-    AssetNotFound,
-
-    /// Generic error when there is a problem with VAA structure
-    #[error("InvalidVAA")]
-    InvalidVAA,
-
-    /// Thrown when fee is enabled for the action, but was not sent with the transaction
-    #[error("FeeTooLow")]
-    FeeTooLow,
-
-    /// Registering asset outside of the wormhole
-    #[error("RegistrationForbidden")]
-    RegistrationForbidden,
-}
-
-impl ContractError {
-    pub fn std(&self) -> StdError {
-        StdError::GenericErr {
-            msg: format!("{}", self),
-        }
-    }
-
-    pub fn std_err<T>(&self) -> Result<T, StdError> {
-        Err(self.std())
-    }
-}

+ 0 - 7
terra/contracts-5/wormhole/src/lib.rs

@@ -1,7 +0,0 @@
-pub mod byte_utils;
-pub mod contract;
-pub mod error;
-pub mod msg;
-pub mod state;
-
-pub use crate::error::ContractError;

+ 0 - 66
terra/contracts-5/wormhole/src/msg.rs

@@ -1,66 +0,0 @@
-use cosmwasm_std::{
-    Binary,
-    Coin,
-};
-use schemars::JsonSchema;
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-use crate::state::{
-    GuardianAddress,
-    GuardianSetInfo,
-};
-
-type HumanAddr = String;
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InstantiateMsg {
-    pub gov_chain: u16,
-    pub gov_address: Binary,
-
-    pub initial_guardian_set: GuardianSetInfo,
-    pub guardian_set_expirity: u64,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum ExecuteMsg {
-    SubmitVAA { vaa: Binary },
-    PostMessage { message: Binary, nonce: u32 },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum QueryMsg {
-    GuardianSetInfo {},
-    VerifyVAA { vaa: Binary, block_time: u64 },
-    GetState {},
-    QueryAddressHex { address: HumanAddr },
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct GuardianSetInfoResponse {
-    pub guardian_set_index: u32,         // Current guardian set index
-    pub addresses: Vec<GuardianAddress>, // List of querdian addresses
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct WrappedRegistryResponse {
-    pub address: HumanAddr,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct GetStateResponse {
-    pub fee: Coin,
-}
-
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub struct GetAddressHexResponse {
-    pub hex: String,
-}

+ 0 - 444
terra/contracts-5/wormhole/src/state.rs

@@ -1,444 +0,0 @@
-use schemars::{
-    JsonSchema,
-};
-use serde::{
-    Deserialize,
-    Serialize,
-};
-
-use cosmwasm_std::{
-    Binary,
-    CanonicalAddr,
-    Coin,
-    StdResult,
-    Storage,
-    Uint128,
-};
-use cosmwasm_storage::{
-    bucket,
-    bucket_read,
-    singleton,
-    singleton_read,
-    Bucket,
-    ReadonlyBucket,
-    ReadonlySingleton,
-    Singleton,
-};
-
-use crate::{
-    byte_utils::ByteUtils,
-    error::ContractError,
-};
-
-use sha3::{
-    Digest,
-    Keccak256,
-};
-
-type HumanAddr = String;
-
-pub static CONFIG_KEY: &[u8] = b"config";
-pub static GUARDIAN_SET_KEY: &[u8] = b"guardian_set";
-pub static SEQUENCE_KEY: &[u8] = b"sequence";
-pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset";
-pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address";
-
-// Guardian set information
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct ConfigInfo {
-    // Current active guardian set
-    pub guardian_set_index: u32,
-
-    // Period for which a guardian set stays active after it has been replaced
-    pub guardian_set_expirity: u64,
-
-    // governance contract details
-    pub gov_chain: u16,
-    pub gov_address: Vec<u8>,
-
-    // Message sending fee
-    pub fee: Coin,
-}
-
-// Validator Action Approval(VAA) data
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct ParsedVAA {
-    pub version: u8,
-    pub guardian_set_index: u32,
-    pub timestamp: u32,
-    pub nonce: u32,
-    pub len_signers: u8,
-
-    pub emitter_chain: u16,
-    pub emitter_address: Vec<u8>,
-    pub sequence: u64,
-    pub consistency_level: u8,
-    pub payload: Vec<u8>,
-
-    pub hash: Vec<u8>,
-}
-
-impl ParsedVAA {
-    /* VAA format:
-
-    header (length 6):
-    0   uint8   version (0x01)
-    1   uint32  guardian set index
-    5   uint8   len signatures
-
-    per signature (length 66):
-    0   uint8       index of the signer (in guardian keys)
-    1   [65]uint8   signature
-
-    body:
-    0   uint32      timestamp (unix in seconds)
-    4   uint32      nonce
-    8   uint16      emitter_chain
-    10  [32]uint8   emitter_address
-    42  uint64      sequence
-    50  uint8       consistency_level
-    51  []uint8     payload
-    */
-
-    pub const HEADER_LEN: usize = 6;
-    pub const SIGNATURE_LEN: usize = 66;
-
-    pub const GUARDIAN_SET_INDEX_POS: usize = 1;
-    pub const LEN_SIGNER_POS: usize = 5;
-
-    pub const VAA_NONCE_POS: usize = 4;
-    pub const VAA_EMITTER_CHAIN_POS: usize = 8;
-    pub const VAA_EMITTER_ADDRESS_POS: usize = 10;
-    pub const VAA_SEQUENCE_POS: usize = 42;
-    pub const VAA_CONSISTENCY_LEVEL_POS: usize = 50;
-    pub const VAA_PAYLOAD_POS: usize = 51;
-
-    // Signature data offsets in the signature block
-    pub const SIG_DATA_POS: usize = 1;
-    // Signature length minus recovery id at the end
-    pub const SIG_DATA_LEN: usize = 64;
-    // Recovery byte is last after the main signature
-    pub const SIG_RECOVERY_POS: usize = Self::SIG_DATA_POS + Self::SIG_DATA_LEN;
-
-    pub fn deserialize(data: &[u8]) -> StdResult<Self> {
-        let version = data.get_u8(0);
-
-        // Load 4 bytes starting from index 1
-        let guardian_set_index: u32 = data.get_u32(Self::GUARDIAN_SET_INDEX_POS);
-        let len_signers = data.get_u8(Self::LEN_SIGNER_POS) as usize;
-        let body_offset: usize = Self::HEADER_LEN + Self::SIGNATURE_LEN * len_signers as usize;
-
-        // Hash the body
-        if body_offset >= data.len() {
-            return ContractError::InvalidVAA.std_err();
-        }
-        let body = &data[body_offset..];
-        let mut hasher = Keccak256::new();
-        hasher.update(body);
-        let hash = hasher.finalize().to_vec();
-
-        // Rehash the hash
-        let mut hasher = Keccak256::new();
-        hasher.update(hash);
-        let hash = hasher.finalize().to_vec();
-
-        // Signatures valid, apply VAA
-        if body_offset + Self::VAA_PAYLOAD_POS > data.len() {
-            return ContractError::InvalidVAA.std_err();
-        }
-
-        let timestamp = data.get_u32(body_offset);
-        let nonce = data.get_u32(body_offset + Self::VAA_NONCE_POS);
-        let emitter_chain = data.get_u16(body_offset + Self::VAA_EMITTER_CHAIN_POS);
-        let emitter_address = data
-            .get_bytes32(body_offset + Self::VAA_EMITTER_ADDRESS_POS)
-            .to_vec();
-        let sequence = data.get_u64(body_offset + Self::VAA_SEQUENCE_POS);
-        let consistency_level = data.get_u8(body_offset + Self::VAA_CONSISTENCY_LEVEL_POS);
-        let payload = data[body_offset + Self::VAA_PAYLOAD_POS..].to_vec();
-
-        Ok(ParsedVAA {
-            version,
-            guardian_set_index,
-            timestamp,
-            nonce,
-            len_signers: len_signers as u8,
-            emitter_chain,
-            emitter_address,
-            sequence,
-            consistency_level,
-            payload,
-            hash,
-        })
-    }
-}
-
-// Guardian address
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct GuardianAddress {
-    pub bytes: Binary, // 20-byte addresses
-}
-
-use crate::contract::FEE_DENOMINATION;
-#[cfg(test)]
-use hex;
-
-#[cfg(test)]
-impl GuardianAddress {
-    pub fn from(string: &str) -> GuardianAddress {
-        GuardianAddress {
-            bytes: hex::decode(string).expect("Decoding failed").into(),
-        }
-    }
-}
-
-// Guardian set information
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct GuardianSetInfo {
-    pub addresses: Vec<GuardianAddress>,
-    // List of guardian addresses
-    pub expiration_time: u64, // Guardian set expiration time
-}
-
-impl GuardianSetInfo {
-    pub fn quorum(&self) -> usize {
-        // allow quorum of 0 for testing purposes...
-        if self.addresses.len() == 0 {
-            return 0;
-        }
-        ((self.addresses.len() * 10 / 3) * 2) / 10 + 1
-    }
-}
-
-// Wormhole contract generic information
-#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct WormholeInfo {
-    // Period for which a guardian set stays active after it has been replaced
-    pub guardian_set_expirity: u64,
-}
-
-pub fn config(storage: &mut dyn Storage) -> Singleton<ConfigInfo> {
-    singleton(storage, CONFIG_KEY)
-}
-
-pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton<ConfigInfo> {
-    singleton_read(storage, CONFIG_KEY)
-}
-
-pub fn guardian_set_set(
-    storage: &mut dyn Storage,
-    index: u32,
-    data: &GuardianSetInfo,
-) -> StdResult<()> {
-    bucket(storage, GUARDIAN_SET_KEY).save(&index.to_be_bytes(), data)
-}
-
-pub fn guardian_set_get(storage: &dyn Storage, index: u32) -> StdResult<GuardianSetInfo> {
-    bucket_read(storage, GUARDIAN_SET_KEY).load(&index.to_be_bytes())
-}
-
-pub fn sequence_set(storage: &mut dyn Storage, emitter: &[u8], sequence: u64) -> StdResult<()> {
-    bucket(storage, SEQUENCE_KEY).save(emitter, &sequence)
-}
-
-pub fn sequence_read(storage: &dyn Storage, emitter: &[u8]) -> u64 {
-    bucket_read(storage, SEQUENCE_KEY)
-        .load(&emitter)
-        .or::<u64>(Ok(0))
-        .unwrap()
-}
-
-pub fn vaa_archive_add(storage: &mut dyn Storage, hash: &[u8]) -> StdResult<()> {
-    bucket(storage, GUARDIAN_SET_KEY).save(hash, &true)
-}
-
-pub fn vaa_archive_check(storage: &dyn Storage, hash: &[u8]) -> bool {
-    bucket_read(storage, GUARDIAN_SET_KEY)
-        .load(&hash)
-        .or::<bool>(Ok(false))
-        .unwrap()
-}
-
-pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket<HumanAddr> {
-    bucket(storage, WRAPPED_ASSET_KEY)
-}
-
-pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<HumanAddr> {
-    bucket_read(storage, WRAPPED_ASSET_KEY)
-}
-
-pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
-    bucket(storage, WRAPPED_ASSET_ADDRESS_KEY)
-}
-
-pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
-    bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY)
-}
-
-pub struct GovernancePacket {
-    pub module: Vec<u8>,
-    pub action: u8,
-    pub chain: u16,
-    pub payload: Vec<u8>,
-}
-
-impl GovernancePacket {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let module = data.get_bytes32(0).to_vec();
-        let action = data.get_u8(32);
-        let chain = data.get_u16(33);
-        let payload = data[35..].to_vec();
-
-        Ok(GovernancePacket {
-            module,
-            action,
-            chain,
-            payload,
-        })
-    }
-}
-
-// action 2
-pub struct GuardianSetUpgrade {
-    pub new_guardian_set_index: u32,
-    pub new_guardian_set: GuardianSetInfo,
-}
-
-impl GuardianSetUpgrade {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        const ADDRESS_LEN: usize = 20;
-
-        let data = data.as_slice();
-        let new_guardian_set_index = data.get_u32(0);
-
-        let n_guardians = data.get_u8(4);
-
-        let mut addresses = vec![];
-
-        for i in 0..n_guardians {
-            let pos = 5 + (i as usize) * ADDRESS_LEN;
-            if pos + ADDRESS_LEN > data.len() {
-                return ContractError::InvalidVAA.std_err();
-            }
-
-            addresses.push(GuardianAddress {
-                bytes: data[pos..pos + ADDRESS_LEN].to_vec().into(),
-            });
-        }
-
-        let new_guardian_set = GuardianSetInfo {
-            addresses,
-            expiration_time: 0,
-        };
-
-        return Ok(GuardianSetUpgrade {
-            new_guardian_set_index,
-            new_guardian_set,
-        });
-    }
-}
-
-// action 3
-pub struct SetFee {
-    pub fee: Coin,
-}
-
-impl SetFee {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-
-        let (_, amount) = data.get_u256(0);
-        let fee = Coin {
-            denom: String::from(FEE_DENOMINATION),
-            amount: Uint128::new(amount),
-        };
-        Ok(SetFee { fee })
-    }
-}
-
-// action 4
-pub struct TransferFee {
-    pub amount: Coin,
-    pub recipient: CanonicalAddr,
-}
-
-impl TransferFee {
-    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
-        let data = data.as_slice();
-        let recipient = data.get_address(0);
-
-        let (_, amount) = data.get_u256(32);
-        let amount = Coin {
-            denom: String::from(FEE_DENOMINATION),
-            amount: Uint128::new(amount),
-        };
-        Ok(TransferFee { amount, recipient })
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    fn build_guardian_set(length: usize) -> GuardianSetInfo {
-        let mut addresses: Vec<GuardianAddress> = Vec::with_capacity(length);
-        for _ in 0..length {
-            addresses.push(GuardianAddress {
-                bytes: vec![].into(),
-            });
-        }
-
-        GuardianSetInfo {
-            addresses,
-            expiration_time: 0,
-        }
-    }
-
-    #[test]
-    fn quardian_set_quorum() {
-        assert_eq!(build_guardian_set(1).quorum(), 1);
-        assert_eq!(build_guardian_set(2).quorum(), 2);
-        assert_eq!(build_guardian_set(3).quorum(), 3);
-        assert_eq!(build_guardian_set(4).quorum(), 3);
-        assert_eq!(build_guardian_set(5).quorum(), 4);
-        assert_eq!(build_guardian_set(6).quorum(), 5);
-        assert_eq!(build_guardian_set(7).quorum(), 5);
-        assert_eq!(build_guardian_set(8).quorum(), 6);
-        assert_eq!(build_guardian_set(9).quorum(), 7);
-        assert_eq!(build_guardian_set(10).quorum(), 7);
-        assert_eq!(build_guardian_set(11).quorum(), 8);
-        assert_eq!(build_guardian_set(12).quorum(), 9);
-        assert_eq!(build_guardian_set(20).quorum(), 14);
-        assert_eq!(build_guardian_set(25).quorum(), 17);
-        assert_eq!(build_guardian_set(100).quorum(), 67);
-    }
-
-    #[test]
-    fn test_deserialize() {
-        let x = hex::decode("080000000901007bfa71192f886ab6819fa4862e34b4d178962958d9b2e3d9437338c9e5fde1443b809d2886eaa69e0f0158ea517675d96243c9209c3fe1d94d5b19866654c6980000000b150000000500020001020304000000000000000000000000000000000000000000000000000000000000000000000a0261626364").unwrap();
-        let v = ParsedVAA::deserialize(x.as_slice()).unwrap();
-        assert_eq!(
-            v,
-            ParsedVAA {
-                version: 8,
-                guardian_set_index: 9,
-                timestamp: 2837,
-                nonce: 5,
-                len_signers: 1,
-                emitter_chain: 2,
-                emitter_address: vec![
-                    0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0
-                ],
-                sequence: 10,
-                consistency_level: 2,
-                payload: vec![97, 98, 99, 100],
-                hash: vec![
-                    195, 10, 19, 96, 8, 61, 218, 69, 160, 238, 165, 142, 105, 119, 139, 121, 212,
-                    73, 238, 179, 13, 80, 245, 224, 75, 110, 163, 8, 185, 132, 55, 34
-                ]
-            }
-        );
-    }
-}

+ 8 - 6
terra/contracts/cw20-wrapped/Cargo.toml

@@ -14,13 +14,15 @@ 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.0"
-cw20-base = { version = "0.2.0", features = ["library"] }
+cw2 = { version = "0.8.0" } 
+cw20 = { version = "0.8.0" } 
+cw20-legacy = { version = "0.2.0", features = ["library"]} 
+cw-storage-plus  = { version = "0.8.0" }
 thiserror = { version = "1.0.20" }
 
 [dev-dependencies]
-cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] }
+cosmwasm-vm = { version = "0.16.0", default-features = false }

+ 150 - 134
terra/contracts/cw20-wrapped/src/contract.rs

@@ -1,48 +1,47 @@
 use cosmwasm_std::{
+    entry_point,
     to_binary,
-    Api,
     Binary,
     CosmosMsg,
+    Deps,
+    DepsMut,
     Env,
-    Extern,
-    HandleResponse,
-    HumanAddr,
-    InitResponse,
-    Querier,
+    MessageInfo,
+    Response,
     StdError,
     StdResult,
-    Storage,
     Uint128,
     WasmMsg,
 };
 
-use cw20_base::{
+use cw2::set_contract_version;
+use cw20_legacy::{
     allowances::{
-        handle_burn_from,
-        handle_decrease_allowance,
-        handle_increase_allowance,
-        handle_send_from,
-        handle_transfer_from,
+        execute_burn_from,
+        execute_decrease_allowance,
+        execute_increase_allowance,
+        execute_send_from,
+        execute_transfer_from,
         query_allowance,
     },
     contract::{
-        handle_mint,
-        handle_send,
-        handle_transfer,
+        execute_mint,
+        execute_send,
+        execute_transfer,
         query_balance,
     },
     state::{
-        token_info,
-        token_info_read,
         MinterData,
         TokenInfo,
+        TOKEN_INFO,
     },
+    ContractError,
 };
 
 use crate::{
     msg::{
-        HandleMsg,
-        InitMsg,
+        ExecuteMsg,
+        InstantiateMsg,
         QueryMsg,
         WrappedAssetInfoResponse,
     },
@@ -55,116 +54,137 @@ use crate::{
 use cw20::TokenInfoResponse;
 use std::string::String;
 
-pub fn init<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+type HumanAddr = String;
+
+// version info for migration info
+const CONTRACT_NAME: &str = "crates.io:cw20-base";
+const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
+
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn instantiate(
+    deps: DepsMut,
     env: Env,
-    msg: InitMsg,
-) -> StdResult<InitResponse> {
+    info: MessageInfo,
+    msg: InstantiateMsg,
+) -> StdResult<Response> {
+    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
+
     // store token info using cw20-base format
     let data = TokenInfo {
         name: msg.name,
         symbol: msg.symbol,
         decimals: msg.decimals,
-        total_supply: Uint128(0),
+        total_supply: Uint128::new(0),
         // set creator as minter
         mint: Some(MinterData {
-            minter: deps.api.canonical_address(&env.message.sender)?,
+            minter: deps.api.addr_canonicalize(&info.sender.as_str())?,
             cap: None,
         }),
     };
-    token_info(&mut deps.storage).save(&data)?;
+    TOKEN_INFO.save(deps.storage, &data)?;
 
     // save wrapped asset info
     let data = WrappedAssetInfo {
         asset_chain: msg.asset_chain,
         asset_address: msg.asset_address,
-        bridge: deps.api.canonical_address(&env.message.sender)?,
+        bridge: deps.api.addr_canonicalize(&info.sender.as_str())?,
     };
-    wrapped_asset_info(&mut deps.storage).save(&data)?;
+    wrapped_asset_info(deps.storage).save(&data)?;
 
     if let Some(mint_info) = msg.mint {
-        handle_mint(deps, env, mint_info.recipient, mint_info.amount)?;
+        execute_mint(deps, env, info, mint_info.recipient, mint_info.amount)
+            .map_err(|e| StdError::generic_err(format!("{}", e)))?;
     }
 
     if let Some(hook) = msg.init_hook {
-        Ok(InitResponse {
-            messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
+        Ok(
+            Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute {
                 contract_addr: hook.contract_addr,
                 msg: hook.msg,
-                send: vec![],
-            })],
-            log: vec![],
-        })
+                funds: vec![],
+            })),
+        )
     } else {
-        Ok(InitResponse::default())
+        Ok(Response::default())
     }
 }
 
-pub fn handle<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn execute(
+    deps: DepsMut,
     env: Env,
-    msg: HandleMsg,
-) -> StdResult<HandleResponse> {
+    info: MessageInfo,
+    msg: ExecuteMsg,
+) -> Result<Response, ContractError> {
     match msg {
         // these all come from cw20-base to implement the cw20 standard
-        HandleMsg::Transfer { recipient, amount } => {
-            Ok(handle_transfer(deps, env, recipient, amount)?)
+        ExecuteMsg::Transfer { recipient, amount } => {
+            Ok(execute_transfer(deps, env, info, recipient, amount)?)
         }
-        HandleMsg::Burn { account, amount } => Ok(handle_burn_from(deps, env, account, amount)?),
-        HandleMsg::Send {
+        ExecuteMsg::Burn { account, amount } => {
+            Ok(execute_burn_from(deps, env, info, account, amount)?)
+        }
+        ExecuteMsg::Send {
             contract,
             amount,
             msg,
-        } => Ok(handle_send(deps, env, contract, amount, msg)?),
-        HandleMsg::Mint { recipient, amount } => handle_mint_wrapped(deps, env, recipient, amount),
-        HandleMsg::IncreaseAllowance {
+        } => Ok(execute_send(deps, env, info, contract, amount, msg)?),
+        ExecuteMsg::Mint { recipient, amount } => {
+            execute_mint_wrapped(deps, env, info, recipient, amount)
+        }
+        ExecuteMsg::IncreaseAllowance {
             spender,
             amount,
             expires,
-        } => Ok(handle_increase_allowance(
-            deps, env, spender, amount, expires,
+        } => Ok(execute_increase_allowance(
+            deps, env, info, spender, amount, expires,
         )?),
-        HandleMsg::DecreaseAllowance {
+        ExecuteMsg::DecreaseAllowance {
             spender,
             amount,
             expires,
-        } => Ok(handle_decrease_allowance(
-            deps, env, spender, amount, expires,
+        } => Ok(execute_decrease_allowance(
+            deps, env, info, spender, amount, expires,
         )?),
-        HandleMsg::TransferFrom {
+        ExecuteMsg::TransferFrom {
             owner,
             recipient,
             amount,
-        } => Ok(handle_transfer_from(deps, env, owner, recipient, amount)?),
-        HandleMsg::BurnFrom { owner, amount } => Ok(handle_burn_from(deps, env, owner, amount)?),
-        HandleMsg::SendFrom {
+        } => Ok(execute_transfer_from(
+            deps, env, info, owner, recipient, amount,
+        )?),
+        ExecuteMsg::BurnFrom { owner, amount } => {
+            Ok(execute_burn_from(deps, env, info, owner, amount)?)
+        }
+        ExecuteMsg::SendFrom {
             owner,
             contract,
             amount,
             msg,
-        } => Ok(handle_send_from(deps, env, owner, contract, amount, msg)?),
+        } => Ok(execute_send_from(
+            deps, env, info, owner, contract, amount, msg,
+        )?),
     }
 }
 
-fn handle_mint_wrapped<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+fn execute_mint_wrapped(
+    deps: DepsMut,
     env: Env,
+    info: MessageInfo,
     recipient: HumanAddr,
     amount: Uint128,
-) -> StdResult<HandleResponse> {
+) -> Result<Response, ContractError> {
     // Only bridge can mint
-    let wrapped_info = wrapped_asset_info_read(&deps.storage).load()?;
-    if wrapped_info.bridge != deps.api.canonical_address(&env.message.sender)? {
-        return Err(StdError::unauthorized());
+    let wrapped_info = wrapped_asset_info_read(deps.storage).load()?;
+    if wrapped_info.bridge != deps.api.addr_canonicalize(&info.sender.as_str())? {
+        return Err(ContractError::Unauthorized {});
     }
 
-    Ok(handle_mint(deps, env, recipient, amount)?)
+    Ok(execute_mint(deps, env, info, recipient, amount)?)
 }
 
-pub fn query<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-    msg: QueryMsg,
-) -> StdResult<Binary> {
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
     match msg {
         QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?),
         // inherited from cw20-base
@@ -176,66 +196,58 @@ pub fn query<S: Storage, A: Api, Q: Querier>(
     }
 }
 
-pub fn query_token_info<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-) -> StdResult<TokenInfoResponse> {
-    let info = token_info_read(&deps.storage).load()?;
-    let res = TokenInfoResponse {
+pub fn query_token_info(deps: Deps) -> StdResult<TokenInfoResponse> {
+    let info = TOKEN_INFO.load(deps.storage)?;
+    Ok(TokenInfoResponse {
         name: String::from("Wormhole:") + info.name.as_str(),
         symbol: String::from("wh") + info.symbol.as_str(),
         decimals: info.decimals,
         total_supply: info.total_supply,
-    };
-    Ok(res)
+    })
 }
 
-pub fn query_wrapped_asset_info<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-) -> StdResult<WrappedAssetInfoResponse> {
-    let info = wrapped_asset_info_read(&deps.storage).load()?;
-    let res = WrappedAssetInfoResponse {
+pub fn query_wrapped_asset_info(deps: Deps) -> StdResult<WrappedAssetInfoResponse> {
+    let info = wrapped_asset_info_read(deps.storage).load()?;
+    Ok(WrappedAssetInfoResponse {
         asset_chain: info.asset_chain,
         asset_address: info.asset_address,
-        bridge: deps.api.human_address(&info.bridge)?,
-    };
-    Ok(res)
+        bridge: deps.api.addr_humanize(&info.bridge)?,
+    })
 }
 
 #[cfg(test)]
 mod tests {
     use super::*;
-    use cosmwasm_std::{
-        testing::{
-            mock_dependencies,
-            mock_env,
-        },
-        HumanAddr,
+    use cosmwasm_std::testing::{
+        mock_dependencies,
+        mock_env,
+        mock_info,
     };
     use cw20::TokenInfoResponse;
 
     const CANONICAL_LENGTH: usize = 20;
 
-    fn get_balance<S: Storage, A: Api, Q: Querier, T: Into<HumanAddr>>(
-        deps: &Extern<S, A, Q>,
-        address: T,
-    ) -> Uint128 {
-        query_balance(&deps, address.into()).unwrap().balance
+    fn get_balance(deps: Deps, address: HumanAddr) -> Uint128 {
+        query_balance(deps, address.into()).unwrap().balance
     }
 
-    fn do_init<S: Storage, A: Api, Q: Querier>(deps: &mut Extern<S, A, Q>, creator: &HumanAddr) {
-        let init_msg = InitMsg {
+    fn do_init(mut deps: DepsMut, creator: &HumanAddr) {
+        let init_msg = InstantiateMsg {
+            name: "Integers".to_string(),
+            symbol: "INT".to_string(),
             asset_chain: 1,
             asset_address: vec![1; 32].into(),
             decimals: 10,
             mint: None,
             init_hook: None,
         };
-        let env = mock_env(creator, &[]);
-        let res = init(deps, env, init_msg).unwrap();
+        let env = mock_env();
+        let info = mock_info(creator, &[]);
+        let res = instantiate(deps, env, info, init_msg).unwrap();
         assert_eq!(0, res.messages.len());
 
         assert_eq!(
-            query_token_info(&deps).unwrap(),
+            query_token_info(deps.as_ref()).unwrap(),
             TokenInfoResponse {
                 name: "Wormhole Wrapped".to_string(),
                 symbol: "WWT".to_string(),
@@ -245,35 +257,36 @@ mod tests {
         );
 
         assert_eq!(
-            query_wrapped_asset_info(&deps).unwrap(),
+            query_wrapped_asset_info(deps.as_ref()).unwrap(),
             WrappedAssetInfoResponse {
                 asset_chain: 1,
                 asset_address: vec![1; 32].into(),
-                bridge: creator.clone(),
+                bridge: deps.api.addr_validate(creator).unwrap(),
             }
         );
     }
 
-    fn do_init_and_mint<S: Storage, A: Api, Q: Querier>(
-        deps: &mut Extern<S, A, Q>,
+    fn do_init_and_mint(
+        mut deps: DepsMut,
         creator: &HumanAddr,
         mint_to: &HumanAddr,
         amount: Uint128,
     ) {
         do_init(deps, creator);
 
-        let msg = HandleMsg::Mint {
+        let msg = ExecuteMsg::Mint {
             recipient: mint_to.clone(),
             amount,
         };
 
-        let env = mock_env(&creator, &[]);
-        let res = handle(deps, env, msg.clone()).unwrap();
+        let env = mock_env();
+        let info = mock_info(creator, &[]);
+        let res = execute(deps.as_mut(), env, info, msg.clone()).unwrap();
         assert_eq!(0, res.messages.len());
-        assert_eq!(get_balance(deps, mint_to), amount);
+        assert_eq!(get_balance(deps.as_ref(), mint_to.clone(),), amount);
 
         assert_eq!(
-            query_token_info(&deps).unwrap(),
+            query_token_info(deps.as_ref()).unwrap(),
             TokenInfoResponse {
                 name: "Wormhole Wrapped".to_string(),
                 symbol: "WWT".to_string(),
@@ -285,29 +298,30 @@ mod tests {
 
     #[test]
     fn can_mint_by_minter() {
-        let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
+        let mut deps = mock_dependencies(&[]);
         let minter = HumanAddr::from("minter");
         let recipient = HumanAddr::from("recipient");
-        let amount = Uint128(222_222_222);
-        do_init_and_mint(&mut deps, &minter, &recipient, amount);
+        let amount = Uint128::new(222_222_222);
+        do_init_and_mint(deps.as_mut(), &minter, &recipient, amount);
     }
 
     #[test]
     fn others_cannot_mint() {
-        let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
+        let mut deps = mock_dependencies(&[]);
         let minter = HumanAddr::from("minter");
         let recipient = HumanAddr::from("recipient");
-        do_init(&mut deps, &minter);
+        do_init(deps.as_mut(), &minter);
 
-        let amount = Uint128(222_222_222);
-        let msg = HandleMsg::Mint {
+        let amount = Uint128::new(222_222_222);
+        let msg = ExecuteMsg::Mint {
             recipient: recipient.clone(),
             amount,
         };
 
         let other_address = HumanAddr::from("other");
-        let env = mock_env(&other_address, &[]);
-        let res = handle(&mut deps, env, msg);
+        let env = mock_env();
+        let info = mock_info(&other_address, &[]);
+        let res = execute(deps.as_mut(), env, info, msg);
         assert_eq!(
             format!("{}", res.unwrap_err()),
             format!("{}", crate::error::ContractError::Unauthorized {})
@@ -316,44 +330,46 @@ mod tests {
 
     #[test]
     fn transfer_balance_success() {
-        let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
+        let mut deps = mock_dependencies(&[]);
         let minter = HumanAddr::from("minter");
         let owner = HumanAddr::from("owner");
-        let amount_initial = Uint128(222_222_222);
-        do_init_and_mint(&mut deps, &minter, &owner, amount_initial);
+        let amount_initial = Uint128::new(222_222_222);
+        do_init_and_mint(deps.as_mut(), &minter, &owner, amount_initial);
 
         // Transfer
         let recipient = HumanAddr::from("recipient");
-        let amount_transfer = Uint128(222_222);
-        let msg = HandleMsg::Transfer {
+        let amount_transfer = Uint128::new(222_222);
+        let msg = ExecuteMsg::Transfer {
             recipient: recipient.clone(),
             amount: amount_transfer,
         };
 
-        let env = mock_env(&owner, &[]);
-        let res = handle(&mut deps, env, msg.clone()).unwrap();
+        let env = mock_env();
+        let info = mock_info(&owner, &[]);
+        let res = execute(deps.as_mut(), env, info, msg.clone()).unwrap();
         assert_eq!(0, res.messages.len());
-        assert_eq!(get_balance(&deps, owner), Uint128(222_000_000));
-        assert_eq!(get_balance(&deps, recipient), amount_transfer);
+        assert_eq!(get_balance(deps.as_ref(), owner), Uint128::new(222_000_000));
+        assert_eq!(get_balance(deps.as_ref(), recipient), amount_transfer);
     }
 
     #[test]
     fn transfer_balance_not_enough() {
-        let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
+        let mut deps = mock_dependencies(&[]);
         let minter = HumanAddr::from("minter");
         let owner = HumanAddr::from("owner");
-        let amount_initial = Uint128(222_221);
-        do_init_and_mint(&mut deps, &minter, &owner, amount_initial);
+        let amount_initial = Uint128::new(222_221);
+        do_init_and_mint(deps.as_mut(), &minter, &owner, amount_initial);
 
         // Transfer
         let recipient = HumanAddr::from("recipient");
-        let amount_transfer = Uint128(222_222);
-        let msg = HandleMsg::Transfer {
+        let amount_transfer = Uint128::new(222_222);
+        let msg = ExecuteMsg::Transfer {
             recipient: recipient.clone(),
             amount: amount_transfer,
         };
 
-        let env = mock_env(&owner, &[]);
-        let _ = handle(&mut deps, env, msg.clone()).unwrap_err(); // Will panic if no error
+        let env = mock_env();
+        let info = mock_info(&owner, &[]);
+        let _ = execute(deps.as_mut(), env, info, msg.clone()).unwrap_err(); // Will panic if no error
     }
 }

+ 2 - 4
terra/contracts/cw20-wrapped/src/lib.rs

@@ -1,9 +1,7 @@
-pub mod contract;
 mod error;
+
+pub mod contract;
 pub mod msg;
 pub mod state;
 
 pub use crate::error::ContractError;
-
-#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
-cosmwasm_std::create_entry_points!(contract);

+ 8 - 6
terra/contracts/cw20-wrapped/src/msg.rs

@@ -6,14 +6,16 @@ use serde::{
 };
 
 use cosmwasm_std::{
+    Addr,
     Binary,
-    HumanAddr,
     Uint128,
 };
 use cw20::Expiration;
 
+type HumanAddr = String;
+
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InitMsg {
+pub struct InstantiateMsg {
     pub name: String,
     pub symbol: String,
     pub asset_chain: u16,
@@ -37,7 +39,7 @@ pub struct InitMint {
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
-pub enum HandleMsg {
+pub enum ExecuteMsg {
     /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions
     Transfer {
         recipient: HumanAddr,
@@ -50,7 +52,7 @@ pub enum HandleMsg {
     Send {
         contract: HumanAddr,
         amount: Uint128,
-        msg: Option<Binary>,
+        msg: Binary,
     },
     /// Implements CW20 "mintable" extension. If authorized, creates amount new tokens
     /// and adds to the recipient balance.
@@ -87,7 +89,7 @@ pub enum HandleMsg {
         owner: HumanAddr,
         contract: HumanAddr,
         amount: Uint128,
-        msg: Option<Binary>,
+        msg: Binary,
     },
     /// Implements CW20 "approval" extension. Destroys tokens forever
     BurnFrom { owner: HumanAddr, amount: Uint128 },
@@ -116,5 +118,5 @@ pub enum QueryMsg {
 pub struct WrappedAssetInfoResponse {
     pub asset_chain: u16,      // Asset chain id
     pub asset_address: Binary, // Asset smart contract address in the original chain
-    pub bridge: HumanAddr,     // Bridge address, authorized to mint and burn wrapped tokens
+    pub bridge: Addr,          // Bridge address, authorized to mint and burn wrapped tokens
 }

+ 4 - 5
terra/contracts/cw20-wrapped/src/state.rs

@@ -7,7 +7,6 @@ use serde::{
 use cosmwasm_std::{
     Binary,
     CanonicalAddr,
-    ReadonlyStorage,
     Storage,
 };
 use cosmwasm_storage::{
@@ -27,12 +26,12 @@ pub struct WrappedAssetInfo {
     pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens
 }
 
-pub fn wrapped_asset_info<S: Storage>(storage: &mut S) -> Singleton<S, WrappedAssetInfo> {
+pub fn wrapped_asset_info(storage: &mut dyn Storage) -> Singleton<WrappedAssetInfo> {
     singleton(storage, KEY_WRAPPED_ASSET)
 }
 
-pub fn wrapped_asset_info_read<S: ReadonlyStorage>(
-    storage: &S,
-) -> ReadonlySingleton<S, WrappedAssetInfo> {
+pub fn wrapped_asset_info_read(
+    storage: &dyn Storage,
+) -> ReadonlySingleton<WrappedAssetInfo> {
     singleton_read(storage, KEY_WRAPPED_ASSET)
 }

+ 9 - 10
terra/contracts/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"
+cosmwasm-vm = { version = "0.16.0", default-features = false }
+serde_json = "1.0"

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 245 - 318
terra/contracts/token-bridge/src/contract.rs


+ 0 - 4
terra/contracts/token-bridge/src/lib.rs

@@ -1,10 +1,6 @@
 #[cfg(test)]
-#[macro_use]
 extern crate lazy_static;
 
 pub mod contract;
 pub mod msg;
 pub mod state;
-
-#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
-cosmwasm_std::create_entry_points!(contract);

+ 10 - 4
terra/contracts/token-bridge/src/msg.rs

@@ -1,13 +1,18 @@
-use cosmwasm_std::{Binary, HumanAddr, Uint128};
-use schemars::JsonSchema;
+use cosmwasm_std::{
+    Binary,
+    Uint128,
+};
 use terraswap::asset::{Asset, AssetInfo};
+use schemars::JsonSchema;
 use serde::{
     Deserialize,
     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,
@@ -18,7 +23,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,
     },
@@ -28,6 +33,7 @@ pub enum HandleMsg {
         asset: AssetInfo,
     },
 
+
     InitiateTransfer {
         asset: Asset,
         recipient_chain: u16,

+ 29 - 27
terra/contracts/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";
@@ -43,57 +44,57 @@ pub struct ConfigInfo {
     pub wrapped_asset_code_id: u64,
 }
 
-pub fn config<S: Storage>(storage: &mut S) -> Singleton<S, ConfigInfo> {
+pub fn config(storage: &mut dyn Storage) -> Singleton<ConfigInfo> {
     singleton(storage, CONFIG_KEY)
 }
 
-pub fn config_read<S: Storage>(storage: &S) -> ReadonlySingleton<S, ConfigInfo> {
+pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton<ConfigInfo> {
     singleton_read(storage, CONFIG_KEY)
 }
 
-pub fn bridge_deposit<S: Storage>(storage: &mut S) -> Bucket<S, Uint128> {
-    bucket(BRIDGE_DEPOSITS, storage)
+pub fn bridge_deposit(storage: &mut dyn Storage) -> Bucket<Uint128> {
+    bucket(storage, BRIDGE_DEPOSITS)
 }
 
-pub fn bridge_deposit_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Uint128> {
-    bucket_read(BRIDGE_DEPOSITS, storage)
+pub fn bridge_deposit_read(storage: &dyn Storage) -> ReadonlyBucket<Uint128> {
+    bucket_read(storage, BRIDGE_DEPOSITS)
 }
 
-pub fn bridge_contracts<S: Storage>(storage: &mut S) -> Bucket<S, Vec<u8>> {
-    bucket(BRIDGE_CONTRACTS, storage)
+pub fn bridge_contracts(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
+    bucket(storage, BRIDGE_CONTRACTS)
 }
 
-pub fn bridge_contracts_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Vec<u8>> {
-    bucket_read(BRIDGE_CONTRACTS, storage)
+pub fn bridge_contracts_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
+    bucket_read(storage, BRIDGE_CONTRACTS)
 }
 
-pub fn wrapped_asset<S: Storage>(storage: &mut S) -> Bucket<S, HumanAddr> {
-    bucket(WRAPPED_ASSET_KEY, storage)
+pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket<HumanAddr> {
+    bucket(storage, WRAPPED_ASSET_KEY)
 }
 
-pub fn wrapped_asset_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, HumanAddr> {
-    bucket_read(WRAPPED_ASSET_KEY, storage)
+pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<HumanAddr> {
+    bucket_read(storage, WRAPPED_ASSET_KEY)
 }
 
-pub fn wrapped_asset_address<S: Storage>(storage: &mut S) -> Bucket<S, Vec<u8>> {
-    bucket(WRAPPED_ASSET_ADDRESS_KEY, storage)
+pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
+    bucket(storage, WRAPPED_ASSET_ADDRESS_KEY)
 }
 
-pub fn wrapped_asset_address_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Vec<u8>> {
-    bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage)
+pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
+    bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY)
 }
 
-pub fn send_native<S: Storage>(
-    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",
         ));
@@ -101,14 +102,15 @@ pub fn send_native<S: Storage>(
     counter_bucket.save(asset_address.as_slice(), &new_total)
 }
 
-pub fn receive_native<S: Storage>(
-    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;

+ 9 - 8
terra/contracts/wormhole/Cargo.toml

@@ -14,20 +14,21 @@ 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"] }
 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"] }
+getrandom = { version = "0.2", features = ["custom"] }
 sha3 = { version = "0.9.1", default-features = false }
 generic-array = { version = "0.14.4" }
 hex = "0.4.2"
 lazy_static = "1.4.0"
 
 [dev-dependencies]
-cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] }
-serde_json = "1.0"
+cosmwasm-vm = { version = "0.16.0", default-features = false }
+serde_json = "1.0"

+ 113 - 138
terra/contracts/wormhole/src/contract.rs

@@ -1,21 +1,20 @@
 use cosmwasm_std::{
+    entry_point,
     has_coins,
-    log,
     to_binary,
-    Api,
     BankMsg,
     Binary,
     Coin,
     CosmosMsg,
+    Deps,
+    DepsMut,
     Env,
-    Extern,
-    HandleResponse,
-    HumanAddr,
-    InitResponse,
-    Querier,
+    MessageInfo,
+    Response,
     StdError,
     StdResult,
     Storage,
+    WasmMsg,
 };
 
 use crate::{
@@ -25,11 +24,12 @@ use crate::{
     },
     error::ContractError,
     msg::{
+        ExecuteMsg,
         GetAddressHexResponse,
         GetStateResponse,
         GuardianSetInfoResponse,
-        HandleMsg,
-        InitMsg,
+        InstantiateMsg,
+        MigrateMsg,
         QueryMsg,
     },
     state::{
@@ -42,6 +42,7 @@ use crate::{
         vaa_archive_add,
         vaa_archive_check,
         ConfigInfo,
+        ContractUpgrade,
         GovernancePacket,
         GuardianAddress,
         GuardianSetInfo,
@@ -59,7 +60,7 @@ use k256::{
             Signature as RecoverableSignature,
         },
         Signature,
-        VerifyKey,
+        VerifyingKey,
     },
     EncodedPoint,
 };
@@ -71,6 +72,8 @@ use sha3::{
 use generic_array::GenericArray;
 use std::convert::TryFrom;
 
+type HumanAddr = String;
+
 // Chain ID of Terra
 const CHAIN_ID: u16 = 3;
 
@@ -78,11 +81,18 @@ const CHAIN_ID: u16 = 3;
 const FEE_AMOUNT: u128 = 10000;
 pub const FEE_DENOMINATION: &str = "uluna";
 
-pub fn init<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {
+    Ok(Response::default())
+}
+
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn instantiate(
+    deps: DepsMut,
     _env: Env,
-    msg: InitMsg,
-) -> StdResult<InitResponse> {
+    _info: MessageInfo,
+    msg: InstantiateMsg,
+) -> StdResult<Response> {
     // Save general wormhole info
     let state = ConfigInfo {
         gov_chain: msg.gov_chain,
@@ -91,41 +101,39 @@ pub fn init<S: Storage, A: Api, Q: Querier>(
         guardian_set_expirity: msg.guardian_set_expirity,
         fee: Coin::new(FEE_AMOUNT, FEE_DENOMINATION), // 0.01 Luna (or 10000 uluna) fee by default
     };
-    config(&mut deps.storage).save(&state)?;
+    config(deps.storage).save(&state)?;
 
     // Add initial guardian set to storage
     guardian_set_set(
-        &mut deps.storage,
+        deps.storage,
         state.guardian_set_index,
         &msg.initial_guardian_set,
     )?;
 
-    Ok(InitResponse::default())
+    Ok(Response::default())
 }
 
-pub fn handle<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
-    env: Env,
-    msg: HandleMsg,
-) -> StdResult<HandleResponse> {
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult<Response> {
     match msg {
-        HandleMsg::PostMessage { message, nonce } => {
-            handle_post_message(deps, env, &message.as_slice(), nonce)
+        ExecuteMsg::PostMessage { message, nonce } => {
+            handle_post_message(deps, env, info, &message.as_slice(), nonce)
         }
-        HandleMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, vaa.as_slice()),
+        ExecuteMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, info, vaa.as_slice()),
     }
 }
 
 /// Process VAA message signed by quardians
-fn handle_submit_vaa<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+fn handle_submit_vaa(
+    deps: DepsMut,
     env: Env,
+    _info: MessageInfo,
     data: &[u8],
-) -> StdResult<HandleResponse> {
-    let state = config_read(&deps.storage).load()?;
+) -> StdResult<Response> {
+    let state = config_read(deps.storage).load()?;
 
-    let vaa = parse_and_verify_vaa(&deps.storage, data, env.block.time)?;
-    vaa_archive_add(&mut deps.storage, vaa.hash.as_slice())?;
+    let vaa = parse_and_verify_vaa(deps.storage, data, env.block.time.seconds())?;
+    vaa_archive_add(deps.storage, vaa.hash.as_slice())?;
 
     if state.gov_chain == vaa.emitter_chain && state.gov_address == vaa.emitter_address {
         if state.guardian_set_index != vaa.guardian_set_index {
@@ -139,11 +147,7 @@ fn handle_submit_vaa<S: Storage, A: Api, Q: Querier>(
     ContractError::InvalidVAAAction.std_err()
 }
 
-fn handle_governance_payload<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
-    env: Env,
-    data: &Vec<u8>,
-) -> StdResult<HandleResponse> {
+fn handle_governance_payload(deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
     let gov_packet = GovernancePacket::deserialize(&data)?;
 
     let module = String::from_utf8(gov_packet.module).unwrap();
@@ -160,7 +164,7 @@ fn handle_governance_payload<S: Storage, A: Api, Q: Querier>(
     }
 
     match gov_packet.action {
-        // 1 is reserved for upgrade / migration
+        1u8 => vaa_update_contract(deps, env, &gov_packet.payload),
         2u8 => vaa_update_guardian_set(deps, env, &gov_packet.payload),
         3u8 => handle_set_fee(deps, env, &gov_packet.payload),
         4u8 => handle_transfer_fee(deps, env, &gov_packet.payload),
@@ -170,8 +174,8 @@ fn handle_governance_payload<S: Storage, A: Api, Q: Querier>(
 
 /// Parses raw VAA data into a struct and verifies whether it contains sufficient signatures of an
 /// active guardian set i.e. is valid according to Wormhole consensus rules
-fn parse_and_verify_vaa<S: Storage>(
-    storage: &S,
+fn parse_and_verify_vaa(
+    storage: &dyn Storage,
     data: &[u8],
     block_time: u64,
 ) -> StdResult<ParsedVAA> {
@@ -239,18 +243,14 @@ fn parse_and_verify_vaa<S: Storage>(
     Ok(vaa)
 }
 
-fn vaa_update_guardian_set<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
-    env: Env,
-    data: &Vec<u8>,
-) -> StdResult<HandleResponse> {
+fn vaa_update_guardian_set(deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
     /* Payload format
     0   uint32 new_index
     4   uint8 len(keys)
     5   [][20]uint8 guardian addresses
     */
 
-    let mut state = config_read(&deps.storage).load()?;
+    let mut state = config_read(deps.storage).load()?;
 
     let GuardianSetUpgrade {
         new_guardian_set_index,
@@ -265,107 +265,89 @@ fn vaa_update_guardian_set<S: Storage, A: Api, Q: Querier>(
 
     state.guardian_set_index = new_guardian_set_index;
 
-    guardian_set_set(
-        &mut deps.storage,
-        state.guardian_set_index,
-        &new_guardian_set,
-    )?;
+    guardian_set_set(deps.storage, state.guardian_set_index, &new_guardian_set)?;
 
-    config(&mut deps.storage).save(&state)?;
+    config(deps.storage).save(&state)?;
 
-    let mut old_guardian_set = guardian_set_get(&deps.storage, old_guardian_set_index)?;
-    old_guardian_set.expiration_time = env.block.time + state.guardian_set_expirity;
-    guardian_set_set(&mut deps.storage, old_guardian_set_index, &old_guardian_set)?;
+    let mut old_guardian_set = guardian_set_get(deps.storage, old_guardian_set_index)?;
+    old_guardian_set.expiration_time = env.block.time.seconds() + state.guardian_set_expirity;
+    guardian_set_set(deps.storage, old_guardian_set_index, &old_guardian_set)?;
 
-    Ok(HandleResponse {
-        messages: vec![],
-        log: vec![
-            log("action", "guardian_set_change"),
-            log("old", old_guardian_set_index),
-            log("new", state.guardian_set_index),
-        ],
-        data: None,
-    })
+    Ok(Response::new()
+        .add_attribute("action", "guardian_set_change")
+        .add_attribute("old", old_guardian_set_index.to_string())
+        .add_attribute("new", state.guardian_set_index.to_string()))
 }
 
-pub fn handle_set_fee<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
-    env: Env,
-    data: &Vec<u8>,
-) -> StdResult<HandleResponse> {
+fn vaa_update_contract(_deps: DepsMut, env: Env, data: &Vec<u8>) -> StdResult<Response> {
+    /* Payload format
+    0   [][32]uint8 new_contract
+    */
+
+    let ContractUpgrade { new_contract } = ContractUpgrade::deserialize(&data)?;
+
+    Ok(Response::new()
+        .add_message(CosmosMsg::Wasm(WasmMsg::Migrate {
+            contract_addr: env.contract.address.to_string(),
+            new_code_id: new_contract,
+            msg: to_binary(&MigrateMsg {})?,
+        }))
+        .add_attribute("action", "contract_upgrade"))
+}
+
+pub fn handle_set_fee(deps: DepsMut, _env: Env, data: &Vec<u8>) -> StdResult<Response> {
     let set_fee_msg = SetFee::deserialize(&data)?;
 
     // Save new fees
-    let mut state = config_read(&mut deps.storage).load()?;
+    let mut state = config_read(deps.storage).load()?;
     state.fee = set_fee_msg.fee;
-    config(&mut deps.storage).save(&state)?;
-
-    Ok(HandleResponse {
-        messages: vec![],
-        log: vec![
-            log("action", "fee_change"),
-            log("new_fee.amount", state.fee.amount),
-            log("new_fee.denom", state.fee.denom),
-        ],
-        data: None,
-    })
+    config(deps.storage).save(&state)?;
+
+    Ok(Response::new()
+        .add_attribute("action", "fee_change")
+        .add_attribute("new_fee.amount", state.fee.amount.to_string())
+        .add_attribute("new_fee.denom", state.fee.denom.to_string()))
 }
 
-pub fn handle_transfer_fee<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
-    env: Env,
-    data: &Vec<u8>,
-) -> StdResult<HandleResponse> {
+pub fn handle_transfer_fee(deps: DepsMut, _env: Env, data: &Vec<u8>) -> StdResult<Response> {
     let transfer_msg = TransferFee::deserialize(&data)?;
 
-    Ok(HandleResponse {
-        messages: vec![CosmosMsg::Bank(BankMsg::Send {
-            from_address: env.contract.address,
-            to_address: deps.api.human_address(&transfer_msg.recipient)?,
-            amount: vec![transfer_msg.amount],
-        })],
-        log: vec![],
-        data: None,
-    })
+    Ok(Response::new().add_message(CosmosMsg::Bank(BankMsg::Send {
+        to_address: deps.api.addr_humanize(&transfer_msg.recipient)?.to_string(),
+        amount: vec![transfer_msg.amount],
+    })))
 }
 
-fn handle_post_message<S: Storage, A: Api, Q: Querier>(
-    deps: &mut Extern<S, A, Q>,
+fn handle_post_message(
+    deps: DepsMut,
     env: Env,
+    info: MessageInfo,
     message: &[u8],
     nonce: u32,
-) -> StdResult<HandleResponse> {
-    let state = config_read(&deps.storage).load()?;
+) -> StdResult<Response> {
+    let state = config_read(deps.storage).load()?;
     let fee = state.fee;
 
     // Check fee
-    if !has_coins(env.message.sent_funds.as_ref(), &fee) {
+    if !has_coins(info.funds.as_ref(), &fee) {
         return ContractError::FeeTooLow.std_err();
     }
 
-    let emitter = extend_address_to_32(&deps.api.canonical_address(&env.message.sender)?);
-
-    let sequence = sequence_read(&deps.storage, emitter.as_slice());
-    sequence_set(&mut deps.storage, emitter.as_slice(), sequence + 1)?;
-
-    Ok(HandleResponse {
-        messages: vec![],
-        log: vec![
-            log("message.message", hex::encode(message)),
-            log("message.sender", hex::encode(emitter)),
-            log("message.chain_id", CHAIN_ID),
-            log("message.nonce", nonce),
-            log("message.sequence", sequence),
-            log("message.block_time", env.block.time),
-        ],
-        data: None,
-    })
+    let emitter = extend_address_to_32(&deps.api.addr_canonicalize(&info.sender.as_str())?);
+    let sequence = sequence_read(deps.storage, emitter.as_slice());
+    sequence_set(deps.storage, emitter.as_slice(), sequence + 1)?;
+
+    Ok(Response::new()
+        .add_attribute("message.message", hex::encode(message))
+        .add_attribute("message.sender", hex::encode(emitter))
+        .add_attribute("message.chain_id", CHAIN_ID.to_string())
+        .add_attribute("message.nonce", nonce.to_string())
+        .add_attribute("message.sequence", sequence.to_string())
+        .add_attribute("message.block_time", env.block.time.seconds().to_string()))
 }
 
-pub fn query<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-    msg: QueryMsg,
-) -> StdResult<Binary> {
+#[cfg_attr(not(feature = "library"), entry_point)]
+pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
     match msg {
         QueryMsg::GuardianSetInfo {} => to_binary(&query_guardian_set_info(deps)?),
         QueryMsg::VerifyVAA { vaa, block_time } => to_binary(&query_parse_and_verify_vaa(
@@ -378,11 +360,9 @@ pub fn query<S: Storage, A: Api, Q: Querier>(
     }
 }
 
-pub fn query_guardian_set_info<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-) -> StdResult<GuardianSetInfoResponse> {
-    let state = config_read(&deps.storage).load()?;
-    let guardian_set = guardian_set_get(&deps.storage, state.guardian_set_index)?;
+pub fn query_guardian_set_info(deps: Deps) -> StdResult<GuardianSetInfoResponse> {
+    let state = config_read(deps.storage).load()?;
+    let guardian_set = guardian_set_get(deps.storage, state.guardian_set_index)?;
     let res = GuardianSetInfoResponse {
         guardian_set_index: state.guardian_set_index,
         addresses: guardian_set.addresses,
@@ -390,33 +370,28 @@ pub fn query_guardian_set_info<S: Storage, A: Api, Q: Querier>(
     Ok(res)
 }
 
-pub fn query_parse_and_verify_vaa<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
+pub fn query_parse_and_verify_vaa(
+    deps: Deps,
     data: &[u8],
     block_time: u64,
 ) -> StdResult<ParsedVAA> {
-    parse_and_verify_vaa(&deps.storage, data, block_time)
+    parse_and_verify_vaa(deps.storage, data, block_time)
 }
 
 // returns the hex of the 32 byte address we use for some address on this chain
-pub fn query_address_hex<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-    address: &HumanAddr,
-) -> StdResult<GetAddressHexResponse> {
+pub fn query_address_hex(deps: Deps, address: &HumanAddr) -> StdResult<GetAddressHexResponse> {
     Ok(GetAddressHexResponse {
-        hex: hex::encode(extend_address_to_32(&deps.api.canonical_address(&address)?)),
+        hex: hex::encode(extend_address_to_32(&deps.api.addr_canonicalize(&address)?)),
     })
 }
 
-pub fn query_state<S: Storage, A: Api, Q: Querier>(
-    deps: &Extern<S, A, Q>,
-) -> StdResult<GetStateResponse> {
-    let state = config_read(&deps.storage).load()?;
+pub fn query_state(deps: Deps) -> StdResult<GetStateResponse> {
+    let state = config_read(deps.storage).load()?;
     let res = GetStateResponse { fee: state.fee };
     Ok(res)
 }
 
-fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool {
+fn keys_equal(a: &VerifyingKey, b: &GuardianAddress) -> bool {
     let mut hasher = Keccak256::new();
 
     let point: EncodedPoint = EncodedPoint::from(a);

+ 0 - 1
terra/contracts/wormhole/src/error.rs

@@ -104,7 +104,6 @@ impl ContractError {
     pub fn std(&self) -> StdError {
         StdError::GenericErr {
             msg: format!("{}", self),
-            backtrace: None,
         }
     }
 

+ 0 - 3
terra/contracts/wormhole/src/lib.rs

@@ -5,6 +5,3 @@ pub mod msg;
 pub mod state;
 
 pub use crate::error::ContractError;
-
-#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
-cosmwasm_std::create_entry_points!(contract);

+ 9 - 3
terra/contracts/wormhole/src/msg.rs

@@ -1,7 +1,6 @@
 use cosmwasm_std::{
     Binary,
     Coin,
-    HumanAddr,
 };
 use schemars::JsonSchema;
 use serde::{
@@ -14,8 +13,10 @@ use crate::state::{
     GuardianSetInfo,
 };
 
+type HumanAddr = String;
+
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
-pub struct InitMsg {
+pub struct InstantiateMsg {
     pub gov_chain: u16,
     pub gov_address: Binary,
 
@@ -25,11 +26,16 @@ pub struct InitMsg {
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
-pub enum HandleMsg {
+pub enum ExecuteMsg {
     SubmitVAA { vaa: Binary },
     PostMessage { message: Binary, nonce: u32 },
 }
 
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub struct MigrateMsg {
+}
+
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
 pub enum QueryMsg {

+ 42 - 27
terra/contracts/wormhole/src/state.rs

@@ -1,6 +1,5 @@
 use schemars::{
     JsonSchema,
-    Set,
 };
 use serde::{
     Deserialize,
@@ -11,7 +10,6 @@ use cosmwasm_std::{
     Binary,
     CanonicalAddr,
     Coin,
-    HumanAddr,
     StdResult,
     Storage,
     Uint128,
@@ -37,6 +35,8 @@ use sha3::{
     Keccak256,
 };
 
+type HumanAddr = String;
+
 pub static CONFIG_KEY: &[u8] = b"config";
 pub static GUARDIAN_SET_KEY: &[u8] = b"guardian_set";
 pub static SEQUENCE_KEY: &[u8] = b"sequence";
@@ -217,62 +217,62 @@ pub struct WormholeInfo {
     pub guardian_set_expirity: u64,
 }
 
-pub fn config<S: Storage>(storage: &mut S) -> Singleton<S, ConfigInfo> {
+pub fn config(storage: &mut dyn Storage) -> Singleton<ConfigInfo> {
     singleton(storage, CONFIG_KEY)
 }
 
-pub fn config_read<S: Storage>(storage: &S) -> ReadonlySingleton<S, ConfigInfo> {
+pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton<ConfigInfo> {
     singleton_read(storage, CONFIG_KEY)
 }
 
-pub fn guardian_set_set<S: Storage>(
-    storage: &mut S,
+pub fn guardian_set_set(
+    storage: &mut dyn Storage,
     index: u32,
     data: &GuardianSetInfo,
 ) -> StdResult<()> {
-    bucket(GUARDIAN_SET_KEY, storage).save(&index.to_be_bytes(), data)
+    bucket(storage, GUARDIAN_SET_KEY).save(&index.to_be_bytes(), data)
 }
 
-pub fn guardian_set_get<S: Storage>(storage: &S, index: u32) -> StdResult<GuardianSetInfo> {
-    bucket_read(GUARDIAN_SET_KEY, storage).load(&index.to_be_bytes())
+pub fn guardian_set_get(storage: &dyn Storage, index: u32) -> StdResult<GuardianSetInfo> {
+    bucket_read(storage, GUARDIAN_SET_KEY).load(&index.to_be_bytes())
 }
 
-pub fn sequence_set<S: Storage>(storage: &mut S, emitter: &[u8], sequence: u64) -> StdResult<()> {
-    bucket(SEQUENCE_KEY, storage).save(emitter, &sequence)
+pub fn sequence_set(storage: &mut dyn Storage, emitter: &[u8], sequence: u64) -> StdResult<()> {
+    bucket(storage, SEQUENCE_KEY).save(emitter, &sequence)
 }
 
-pub fn sequence_read<S: Storage>(storage: &S, emitter: &[u8]) -> u64 {
-    bucket_read(SEQUENCE_KEY, storage)
+pub fn sequence_read(storage: &dyn Storage, emitter: &[u8]) -> u64 {
+    bucket_read(storage, SEQUENCE_KEY)
         .load(&emitter)
         .or::<u64>(Ok(0))
         .unwrap()
 }
 
-pub fn vaa_archive_add<S: Storage>(storage: &mut S, hash: &[u8]) -> StdResult<()> {
-    bucket(GUARDIAN_SET_KEY, storage).save(hash, &true)
+pub fn vaa_archive_add(storage: &mut dyn Storage, hash: &[u8]) -> StdResult<()> {
+    bucket(storage, GUARDIAN_SET_KEY).save(hash, &true)
 }
 
-pub fn vaa_archive_check<S: Storage>(storage: &S, hash: &[u8]) -> bool {
-    bucket_read(GUARDIAN_SET_KEY, storage)
+pub fn vaa_archive_check(storage: &dyn Storage, hash: &[u8]) -> bool {
+    bucket_read(storage, GUARDIAN_SET_KEY)
         .load(&hash)
         .or::<bool>(Ok(false))
         .unwrap()
 }
 
-pub fn wrapped_asset<S: Storage>(storage: &mut S) -> Bucket<S, HumanAddr> {
-    bucket(WRAPPED_ASSET_KEY, storage)
+pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket<HumanAddr> {
+    bucket(storage, WRAPPED_ASSET_KEY)
 }
 
-pub fn wrapped_asset_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, HumanAddr> {
-    bucket_read(WRAPPED_ASSET_KEY, storage)
+pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<HumanAddr> {
+    bucket_read(storage, WRAPPED_ASSET_KEY)
 }
 
-pub fn wrapped_asset_address<S: Storage>(storage: &mut S) -> Bucket<S, Vec<u8>> {
-    bucket(WRAPPED_ASSET_ADDRESS_KEY, storage)
+pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket<Vec<u8>> {
+    bucket(storage, WRAPPED_ASSET_ADDRESS_KEY)
 }
 
-pub fn wrapped_asset_address_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Vec<u8>> {
-    bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage)
+pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket<Vec<u8>> {
+    bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY)
 }
 
 pub struct GovernancePacket {
@@ -299,12 +299,27 @@ impl GovernancePacket {
     }
 }
 
+// action 1
+pub struct ContractUpgrade  {
+    pub new_contract: u64,
+}
+
 // action 2
 pub struct GuardianSetUpgrade {
     pub new_guardian_set_index: u32,
     pub new_guardian_set: GuardianSetInfo,
 }
 
+impl ContractUpgrade {
+    pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
+        let data = data.as_slice();
+        let new_contract = data.get_u64(24);
+        Ok(ContractUpgrade {
+            new_contract,
+        })
+    }
+}
+
 impl GuardianSetUpgrade {
     pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
         const ADDRESS_LEN: usize = 20;
@@ -351,7 +366,7 @@ impl SetFee {
         let (_, amount) = data.get_u256(0);
         let fee = Coin {
             denom: String::from(FEE_DENOMINATION),
-            amount: Uint128(amount),
+            amount: Uint128::new(amount),
         };
         Ok(SetFee { fee })
     }
@@ -371,7 +386,7 @@ impl TransferFee {
         let (_, amount) = data.get_u256(32);
         let amount = Coin {
             denom: String::from(FEE_DENOMINATION),
-            amount: Uint128(amount),
+            amount: Uint128::new(amount),
         };
         Ok(TransferFee { amount, recipient })
     }

+ 170 - 113
terra/tools/deploy.js

@@ -1,5 +1,10 @@
 import { Wallet, LCDClient, MnemonicKey } from "@terra-money/terra.js";
-import { StdFee, MsgInstantiateContract, MsgExecuteContract, MsgStoreCode } from "@terra-money/terra.js";
+import {
+  StdFee,
+  MsgInstantiateContract,
+  MsgExecuteContract,
+  MsgStoreCode,
+} from "@terra-money/terra.js";
 import { readFileSync, readdirSync } from "fs";
 
 // TODO: Workaround /tx/estimate_fee errors.
@@ -37,139 +42,191 @@ async function main() {
   await wallet.sequence();
 
   // Deploy WASM blobs.
-  const artifacts = readdirSync('../artifacts/');
+  // Read a list of files from directory containing compiled contracts.
+  const artifacts = readdirSync("../artifacts/");
+
+  // Sort them to get a determinstic list for consecutive code ids.
   artifacts.sort();
+  artifacts.reverse();
+
+  const hardcodedGas = {
+    "cw20_base.wasm": 4000000,
+    "cw20_wrapped.wasm": 4000000,
+    "wormhole.wasm": 5000000,
+    "token_bridge.wasm": 6000000,
+  };
+
+  // Deploy all found WASM files and assign Code IDs.
+  const codeIds = {};
   for (const artifact in artifacts) {
-    console.log(artifact);
-    console.log(artifacts.hasOwnProperty(artifact));
-    if(artifacts.hasOwnProperty(artifact) && artifacts[artifact].includes('.wasm')) {
-        const file = artifacts[artifact];
-        const contract_bytes = readFileSync(`../artifacts/${file}`);
-        console.log(`Storing Bytes, ${contract_bytes.length}, for ${file}`);
-        const store_code = new MsgStoreCode(
-            wallet.key.accAddress,
-            contract_bytes.toString('base64'),
-        );
-
-        try {
-            const tx = await wallet.createAndSignTx({
-                msgs: [store_code],
-                memo: '',
-                fee: new StdFee(
-                    3000000,
-                    { uluna: "100000" }
-                )
-            });
-
-            const rs = await terra.tx.broadcast(tx);
-
-            console.log(JSON.stringify(rs, null, 2));
-            await wallet.sequence();
-        } catch (e) {
-            console.log('Failed to Execute');
-        }
+    if (
+      artifacts.hasOwnProperty(artifact) &&
+      artifacts[artifact].includes(".wasm")
+    ) {
+      const file = artifacts[artifact];
+      const contract_bytes = readFileSync(`../artifacts/${file}`);
+
+      console.log(`Storing WASM: ${file} (${contract_bytes.length} bytes)`);
+
+      const store_code = new MsgStoreCode(
+        wallet.key.accAddress,
+        contract_bytes.toString("base64")
+      );
+
+      try {
+        const tx = await wallet.createAndSignTx({
+          msgs: [store_code],
+          memo: "",
+          fee: new StdFee(hardcodedGas[artifacts[artifact]], {
+            uluna: "100000",
+          }),
+        });
+
+        const rs = await terra.tx.broadcast(tx);
+        const ci = /"code_id","value":"([^"]+)/gm.exec(rs.raw_log)[1];
+        codeIds[file] = parseInt(ci);
+      } catch (e) {
+        console.log("Failed to Execute");
+      }
     }
   }
 
-  const govChain = 1;
-  const govAddress = "0000000000000000000000000000000000000000000000000000000000000004";
+  console.log(codeIds);
 
-  //Instantiate Contracts
-  wallet.createAndSignTx({
+  // Governance constants defined by the Wormhole spec.
+  const govChain = 1;
+  const govAddress =
+    "0000000000000000000000000000000000000000000000000000000000000004";
+  const addresses = {};
+
+  // Instantiate Wormhole
+  console.log("Instantiating Wormhole");
+  await wallet
+    .createAndSignTx({
       msgs: [
         new MsgInstantiateContract(
-            wallet.key.accAddress,
-            undefined,
-            2,
-            {
-                gov_chain: govChain,
-                gov_address: Buffer.from(govAddress, 'hex').toString('base64'),
-                guardian_set_expirity: 86400,
-                initial_guardian_set: {
-                    addresses: [
-                        {
-                            bytes: Buffer.from('beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe', 'hex').toString('base64'),
-                        }
-                    ],
-                    expiration_time: 0
+          wallet.key.accAddress,
+          wallet.key.accAddress,
+          codeIds["wormhole.wasm"],
+          {
+            gov_chain: govChain,
+            gov_address: Buffer.from(govAddress, "hex").toString("base64"),
+            guardian_set_expirity: 86400,
+            initial_guardian_set: {
+              addresses: [
+                {
+                  bytes: Buffer.from(
+                    "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe",
+                    "hex"
+                  ).toString("base64"),
                 },
+              ],
+              expiration_time: 0,
             },
-        )
-    ],
-    memo:'',
-  })
-  .then(tx => terra.tx.broadcast(tx))
-  .then(rs => console.log(rs));
-
-  wallet.createAndSignTx({
+          }
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => {
+      const address = /"contract_address","value":"([^"]+)/gm.exec(
+        rs.raw_log
+      )[1];
+      addresses["wormhole.wasm"] = address;
+    });
+
+  console.log("Instantiating Token Bridge");
+  await wallet
+    .createAndSignTx({
       msgs: [
         new MsgInstantiateContract(
-            wallet.key.accAddress,
-            undefined,
-            4,
-            {
-                owner: deployer.key.accAddress,
-                gov_chain: govChain,
-                gov_address: Buffer.from(govAddress, 'hex').toString('base64'),
-                wormhole_contract: "",
-                wrapped_asset_code_id: 2,
-            },
-        )
-    ],
-    memo:'',
-  })
-  .then(tx => terra.tx.broadcast(tx))
-  .then(rs => console.log(rs));
-
-  wallet.createAndSignTx({
+          wallet.key.accAddress,
+          wallet.key.accAddress,
+          codeIds["token_bridge.wasm"],
+          {
+            owner: wallet.key.accAddress,
+            gov_chain: govChain,
+            gov_address: Buffer.from(govAddress, "hex").toString("base64"),
+            wormhole_contract: addresses["wormhole.wasm"],
+            wrapped_asset_code_id: 2,
+          }
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => {
+      const address = /"contract_address","value":"([^"]+)/gm.exec(
+        rs.raw_log
+      )[1];
+      addresses["token_bridge.wasm"] = address;
+    });
+
+  await wallet
+    .createAndSignTx({
       msgs: [
         new MsgInstantiateContract(
-            wallet.key.accAddress,
-            undefined,
-            3,
-            {
-                name: "MOCK",
-                symbol: "MCK",
-                decimals: 6,
-                initial_balances: [
-                    {
-                        "address": deployer.key.acc_address,
-                        "amount": "100000000"
-                    }
-                ],
-                mint: null,
-            },
-        )
-    ],
-    memo:'',
-  })
-  .then(tx => terra.tx.broadcast(tx))
-  .then(rs => console.log(rs));
+          wallet.key.accAddress,
+          undefined,
+          codeIds["cw20_base.wasm"],
+          {
+            name: "MOCK",
+            symbol: "MCK",
+            decimals: 6,
+            initial_balances: [
+              {
+                address: wallet.key.accAddress,
+                amount: "100000000",
+              },
+            ],
+            mint: null,
+          }
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => {
+      const address = /"contract_address","value":"([^"]+)/gm.exec(
+        rs.raw_log
+      )[1];
+      addresses["mock.wasm"] = address;
+    });
+
+  console.log(addresses);
 
   const registrations = [
-    '01000000000100c9f4230109e378f7efc0605fb40f0e1869f2d82fda5b1dfad8a5a2dafee85e033d155c18641165a77a2db6a7afbf2745b458616cb59347e89ae0c7aa3e7cc2d400000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000001c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f',
-    '01000000000100e2e1975d14734206e7a23d90db48a6b5b6696df72675443293c6057dcb936bf224b5df67d32967adeb220d4fe3cb28be515be5608c74aab6adb31099a478db5c01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16'
+    "01000000000100c9f4230109e378f7efc0605fb40f0e1869f2d82fda5b1dfad8a5a2dafee85e033d155c18641165a77a2db6a7afbf2745b458616cb59347e89ae0c7aa3e7cc2d400000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000001c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f",
+    "01000000000100e2e1975d14734206e7a23d90db48a6b5b6696df72675443293c6057dcb936bf224b5df67d32967adeb220d4fe3cb28be515be5608c74aab6adb31099a478db5c01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16",
   ];
 
-  registrations.forEach(registration => {
-    wallet.createAndSignTx({
-      msgs: [
-          new MsgExecuteContract(
+  for (const registration in registrations) {
+    if (registrations.hasOwnProperty(registration)) {
+      console.log('Registering');
+      await wallet
+        .createAndSignTx({
+          msgs: [
+            new MsgExecuteContract(
               wallet.key.accAddress,
-              "",
+              addresses["token_bridge.wasm"],
               {
-                  submit_vaa: {
-                      data: Buffer.from(registration, 'hex'),
-                  },
+                submit_vaa: {
+                  data: Buffer.from(registrations[registration], "hex").toString('base64'),
+                },
               },
               { uluna: 1000 }
-          ),
-      ],
-      memo: '',
-    })
-    .then(tx => terra.tx.broadcast(tx))
-    .then(rs => console.log(rs));
-  });
+            ),
+          ],
+          memo: "",
+          fee: new StdFee(2000000, {
+            uluna: "100000",
+          }),
+        })
+        .then((tx) => terra.tx.broadcast(tx))
+        .then((rs) => console.log(rs));
+    }
+  }
 }
 
-main()
+main();

+ 1 - 0
terra/tools/deploy.sh

@@ -11,5 +11,6 @@ done
 sleep 2
 
 npm ci && node deploy.js
+
 echo "Going to sleep, interrupt if running manually"
 sleep infinity

+ 133 - 0
terra/tools/migrate.js

@@ -0,0 +1,133 @@
+import { Wallet, LCDClient, MnemonicKey } from "@terra-money/terra.js";
+import {
+  StdFee,
+  MsgExecuteContract,
+  MsgInstantiateContract,
+  MsgMigrateContract,
+  MsgStoreCode,
+  MsgUpdateContractAdmin,
+} from "@terra-money/terra.js";
+import { readFileSync, readdirSync } from "fs";
+
+async function main() {
+  const terra = new LCDClient({
+    URL: "http://localhost:1317",
+    chainID: "localterra",
+  });
+
+  const wallet = terra.wallet(
+    new MnemonicKey({
+      mnemonic:
+        "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
+    })
+  );
+
+  const hardcodedGas = {
+    "wormhole.wasm": 5000000,
+  };
+
+  // Deploy Wormhole alone.
+  const file = "wormhole.wasm";
+  const contract_bytes = readFileSync(`../artifacts/${file}`);
+  console.log(`Storing WASM: ${file} (${contract_bytes.length} bytes)`);
+
+  // Get new code id.
+  const store_code = new MsgStoreCode(
+    wallet.key.accAddress,
+    contract_bytes.toString("base64")
+  );
+
+  const codeIds = {};
+  try {
+    const tx = await wallet.createAndSignTx({
+      msgs: [store_code],
+      memo: "",
+      fee: new StdFee(hardcodedGas["wormhole.wasm"], {
+        uluna: "100000",
+      }),
+    });
+
+    const rs = await terra.tx.broadcast(tx);
+    const ci = /"code_id","value":"([^"]+)/gm.exec(rs.raw_log)[1];
+    codeIds[file] = parseInt(ci);
+  } catch (e) {
+    console.log("Failed to Execute");
+  }
+
+  // Perform a Centralised update.
+  await wallet
+    .createAndSignTx({
+      msgs: [
+        new MsgMigrateContract(
+          wallet.key.accAddress,
+          "terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5",
+          codeIds["wormhole.wasm"],
+          {
+              "action": ""
+          },
+          { uluna: 1000 }
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => console.log(rs));
+
+  // Set the Admin to the contract.
+  await wallet
+    .createAndSignTx({
+      msgs: [
+        new MsgUpdateContractAdmin(
+          wallet.key.accAddress,
+          "terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5",
+          "terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5"
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => console.log(rs));
+
+  // Deploy a new CodeID.
+  try {
+    const tx = await wallet.createAndSignTx({
+      msgs: [store_code],
+      memo: "",
+      fee: new StdFee(hardcodedGas["wormhole.wasm"], {
+        uluna: "100000",
+      }),
+    });
+
+    const rs = await terra.tx.broadcast(tx);
+    const ci = /"code_id","value":"([^"]+)/gm.exec(rs.raw_log)[1];
+    codeIds[file] = parseInt(ci);
+  } catch (e) {
+    console.log("Failed to Execute");
+  }
+
+  const upgradeVAA = '010000000001008928c70a029a924d334a24587e9d2ddbcfa7250d7ba61200e86b16966ef2bbd675fb759aa7a47c6392482ef073e9a6d7c4980dc53ed6f90fc84331486e284912000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000004e78c580000000000000000000000000000000000000000000000000000000000436f72650100030000000000000000000000000000000000000000000000000000000000000005';
+
+  // Perform a decentralised update with a signed VAA.
+  await wallet
+    .createAndSignTx({
+      msgs: [
+        new MsgExecuteContract(
+          wallet.key.accAddress,
+          "terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5",
+          {
+            submit_v_a_a: {
+              vaa: Buffer.from(upgradeVAA, "hex").toString(
+                "base64"
+              ),
+            },
+          },
+          { uluna: 1000 }
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => terra.tx.broadcast(tx))
+    .then((rs) => console.log(rs));
+}
+
+main();

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů