Browse Source

terra/contracts: columbus-5 migration for cw20-wrapped

Change-Id: I32a703cdeb60dcf288907df6318ae504171fc5f0
Reisen 4 năm trước cách đây
mục cha
commit
3cbbc6f2b8

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

@@ -18,6 +18,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"] }
+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" }

+ 149 - 134
terra/contracts-5/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,136 @@ 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> {
+pub fn query(deps: Deps, msg: QueryMsg) -> StdResult<Binary> {
     match msg {
         QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?),
         // inherited from cw20-base
@@ -176,66 +195,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 +256,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 +297,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 +329,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-5/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-5/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-5/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)
 }