Skip to content

Commit

Permalink
Merge pull request #2 from oraichain/feat/withdraw-asset-ibc-wasm
Browse files Browse the repository at this point in the history
Feat/withdraw asset ibc wasm
  • Loading branch information
trung2891 authored Aug 12, 2024
2 parents b7faaaa + 6e0658d commit 14d852c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/adapters/ibc/orai-ibc-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ skip = { workspace = true }
thiserror = { workspace = true }
cw20-ics20-msg = { workspace = true }
cw-utils = { workspace = true }
cw-controllers = { workspace = true }

[dev-dependencies]
cosmos-sdk-proto = { workspace = true }
Expand Down
46 changes: 43 additions & 3 deletions contracts/adapters/ibc/orai-ibc-wasm/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{
error::{ContractError, ContractResult},
state::{ENTRY_POINT_CONTRACT_ADDRESS, IBC_WASM_CONTRACT_ADDRESS},
state::{ENTRY_POINT_CONTRACT_ADDRESS, IBC_WASM_CONTRACT_ADDRESS, OWNER},
};
use cosmwasm_std::{
entry_point, from_json, to_json_binary, DepsMut, Env, MessageInfo, Response, WasmMsg,
entry_point, from_json, to_json_binary, Addr, DepsMut, Empty, Env, MessageInfo, Response,
WasmMsg,
};
use cw2::set_contract_version;

Expand Down Expand Up @@ -31,6 +32,9 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Resp
// Store the entry point contract address
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?;
IBC_WASM_CONTRACT_ADDRESS.save(deps.storage, &checked_ibc_wasm_contract_address)?;
if let Some(owner) = msg.new_owner {
OWNER.set(deps, Some(owner))?;
}

Ok(Response::new()
.add_attribute("action", "migrate")
Expand All @@ -56,7 +60,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn instantiate(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
info: MessageInfo,
msg: InstantiateMsg,
) -> ContractResult<Response> {
// Set contract version
Expand All @@ -72,6 +76,7 @@ pub fn instantiate(
// Store the entry point contract address
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?;
IBC_WASM_CONTRACT_ADDRESS.save(deps.storage, &checked_ibc_wasm_contract_address)?;
OWNER.set(deps, Some(info.sender))?;

Ok(Response::new()
.add_attribute("action", "instantiate")
Expand Down Expand Up @@ -142,9 +147,44 @@ pub fn execute(
}
execute_ibc_wasm_transfer(deps, env, info, ibc_wasm_info, coin)
}
ExecuteMsg::UpdateOwner { new_owner } => execute_update_owner(deps, info, new_owner),
ExecuteMsg::WithdrawAsset { coin, receiver } => {
execute_withdraw_asset(deps, info, coin, receiver)
}
}
}

// update new owner
fn execute_update_owner(
deps: DepsMut,
info: MessageInfo,
new_owner: Addr,
) -> ContractResult<Response> {
OWNER.execute_update_admin::<Empty, Empty>(deps, info, Some(new_owner.clone()))?;

Ok(Response::new().add_attributes(vec![
("action", "update_owner"),
("new_owner", new_owner.as_str()),
]))
}

// withdraw stuck coin and transfer back to user
fn execute_withdraw_asset(
deps: DepsMut,
info: MessageInfo,
coin: Asset,
receiver: Option<Addr>,
) -> ContractResult<Response> {
OWNER.assert_admin(deps.as_ref(), &info.sender)?;
let receiver = receiver.unwrap_or(info.sender);

let msg = coin.transfer(receiver.as_str());

Ok(Response::new()
.add_attributes(vec![("action", "withdraw_asset")])
.add_message(msg))
}

// Converts the given info and coin into a ibc wasm transfer message,
fn execute_ibc_wasm_transfer(
deps: DepsMut,
Expand Down
4 changes: 4 additions & 0 deletions contracts/adapters/ibc/orai-ibc-wasm/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::{OverflowError, StdError};
use cw_controllers::AdminError;
use cw_utils::PaymentError;
use skip::error::SkipError;
use thiserror::Error;
Expand All @@ -19,6 +20,9 @@ pub enum ContractError {
#[error("{0}")]
Payment(#[from] PaymentError),

#[error("{0}")]
AdminError(#[from] AdminError),

#[error("Unauthorized")]
Unauthorized,

Expand Down
2 changes: 2 additions & 0 deletions contracts/adapters/ibc/orai-ibc-wasm/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use cosmwasm_std::Addr;
use cw_controllers::Admin;
use cw_storage_plus::Item;

pub const ENTRY_POINT_CONTRACT_ADDRESS: Item<Addr> = Item::new("entry_point_contract_address");
pub const IBC_WASM_CONTRACT_ADDRESS: Item<Addr> = Item::new("checked_ibc_wasm_contract_address");
pub const OWNER: Admin = Admin::new("owner");
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@

use cosmwasm_std::{
testing::{mock_dependencies, mock_env, mock_info}, to_json_binary, Addr, Coin, SubMsg, Uint128, WasmMsg
testing::{mock_dependencies, mock_env, mock_info}, to_json_binary, Addr, BankMsg, Coin, CosmosMsg, SubMsg, Uint128, WasmMsg
};

use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg};
use cw20_ics20_msg::msg::TransferBackMsg;
use cw_controllers::AdminError;
use skip::{asset::Asset, ibc_wasm::ExecuteMsg};
use skip_api_ibc_adapter_orai_ibc_wasm::{
error::ContractResult, state::{ENTRY_POINT_CONTRACT_ADDRESS, IBC_WASM_CONTRACT_ADDRESS},
contract::execute, error::{ContractError, ContractResult}, state::{ENTRY_POINT_CONTRACT_ADDRESS, IBC_WASM_CONTRACT_ADDRESS, OWNER}
};
use test_case::test_case;

Expand Down Expand Up @@ -145,3 +146,18 @@ fn test_execute_ibc_transfer(params: Params) -> ContractResult<()> {

Ok(())
}


#[test]
fn test_withdraw_stuck_asset() {
let mut deps = mock_dependencies();
OWNER.set(deps.as_mut(), Some(Addr::unchecked("admin"))).unwrap();

// case 1: unauthorized
let err = execute(deps.as_mut(), mock_env(), mock_info("addr000", &[]), ExecuteMsg::WithdrawAsset { coin: Asset::Native(Coin { denom: "orai".to_string(), amount: Uint128::new(1000000) }), receiver: Some(Addr::unchecked("receiver")) }).unwrap_err();
assert_eq!(err, ContractError::AdminError(AdminError::NotAdmin { }));

// case 2: success
let res = execute(deps.as_mut(), mock_env(), mock_info("admin", &[]), ExecuteMsg::WithdrawAsset { coin: Asset::Native(Coin { denom: "orai".to_string(), amount: Uint128::new(1000000) }), receiver: Some(Addr::unchecked("receiver")) }).unwrap();
assert_eq!(res.messages, vec![SubMsg::new(CosmosMsg::Bank(BankMsg::Send { to_address: "receiver".to_string(), amount: vec![Coin{denom: "orai".to_string(), amount: Uint128::new(1000000)}] }))]);
}
10 changes: 9 additions & 1 deletion packages/skip/src/ibc_wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{asset::Asset, error::SkipError};
use std::convert::From;

use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Coin, Coins, StdError};
use cosmwasm_std::{Addr, Coin, Coins, StdError};
use cw20::Cw20ReceiveMsg;
use cw20_ics20_msg::msg::TransferBackMsg;

Expand All @@ -16,6 +16,7 @@ use cw20_ics20_msg::msg::TransferBackMsg;
pub struct MigrateMsg {
pub entry_point_contract_address: String,
pub ibc_wasm_contract_address: String,
pub new_owner: Option<Addr>,
}
///////////////////
/// INSTANTIATE ///
Expand All @@ -40,6 +41,13 @@ pub enum ExecuteMsg {
coin: Asset,
},
Receive(Cw20ReceiveMsg),
UpdateOwner {
new_owner: Addr,
},
WithdrawAsset {
coin: Asset,
receiver: Option<Addr>,
},
}
#[cw_serde]
pub enum Cw20HookMsg {
Expand Down

0 comments on commit 14d852c

Please sign in to comment.