Skip to content

Commit

Permalink
chore: withdraw stuck asset
Browse files Browse the repository at this point in the history
  • Loading branch information
trung2891 committed Nov 22, 2024
1 parent fb456b1 commit 1ec0d2c
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 1 deletion.
16 changes: 15 additions & 1 deletion contracts/entry-point/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::{
error::{ContractError, ContractResult},
execute::{
execute_post_swap_action, execute_swap_and_action, execute_swap_and_action_with_recover,
execute_universal_swap, execute_update_config, execute_user_swap, receive_cw20,
execute_universal_swap, execute_update_config, execute_user_swap, execute_withdraw_asset,
receive_cw20,
},
query::{query_ibc_transfer_adapter_contract, query_swap_venue_adapter_contract},
reply::{reply_swap_and_action_with_recover, RECOVER_REPLY_ID},
Expand All @@ -16,6 +17,7 @@ use cosmwasm_std::{
StdResult,
};
use cw2::set_contract_version;
use oraiswap::universal_swap_memo::Memo;
use skip::entry_point::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};

///////////////
Expand Down Expand Up @@ -220,6 +222,9 @@ pub fn execute(
ibc_wasm_contract_address,
),
ExecuteMsg::UniversalSwap { memo } => execute_universal_swap(deps, env, info, None, memo),
ExecuteMsg::WithdrawAsset { coin, receiver } => {
execute_withdraw_asset(deps, info, coin, receiver)
}
}
}

Expand All @@ -246,3 +251,12 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
}
}
}

#[test]
fn test_memo() {
let memo = "CpcBCgdvcmFpZGV4EosBCogBCj9vcmFpMTl0dGcwajd3NWtyODNqczMydG13bnd4eGRxOXJrbXc0bTNkN21uMmoyaGtwdWd3d2E0dHN6d3Nua2cSP29yYWkxNXVuOG1zeDNuNXpmOWFobHhtZmVxZDJrd2E1d20wbnJweGVyMzA0bTluZDVxNnFxMGc2c2t1NXBkZBoEb3JhaRIBMBiA/I+Y1c7ygxgiLyItCitvcmFpMW15Y21oeXJtZDZkdXNwNDA4cnRqZ3psazc3Mzh2aHRncXloeHh0KitvcmFpMW15Y21oeXJtZDZkdXNwNDA4cnRqZ3psazc3Mzh2aHRncXloeHh0";
println!(
"{:?}",
Memo::decode_memo(Binary::from_base64(memo).unwrap()).unwrap()
);
}
18 changes: 18 additions & 0 deletions contracts/entry-point/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ pub fn receive_cw20(
/// EXECUTE ENTRYPOINTS ///
///////////////////////////

// withdraw stuck coin and transfer back to user
// only owner can execute
pub fn execute_withdraw_asset(
deps: DepsMut,
info: MessageInfo,
coin: Asset,
receiver: Option<Addr>,
) -> Result<Response, ContractError> {
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))
}

// update config
pub fn execute_update_config(
deps: DepsMut,
Expand Down
139 changes: 139 additions & 0 deletions contracts/entry-point/tests/test_withdraw_asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use cosmwasm_std::{
testing::{mock_dependencies, mock_env, mock_info},
Addr, BankMsg, Coin, CosmosMsg, SubMsg, Uint128,
};
use skip::{asset::Asset, entry_point::ExecuteMsg, swap::SwapVenue};
use skip_api_entry_point::{
error::ContractError,
state::{BLOCKED_CONTRACT_ADDRESSES, IBC_TRANSFER_CONTRACT_ADDRESS, OWNER, SWAP_VENUE_MAP},
};
use test_case::test_case;

/*
Test Cases:
Expect Response
- Happy Path (tests the adapter and blocked contract addresses are stored correctly)
Expect Error:
- Unauthorized
Expect Error
- Duplicate Swap Venue Names
*/

// Define test parameters
struct Params {
owner: Option<Addr>,
coin: Asset,
sender: String,
expected_error: Option<ContractError>,
expected_msgs: Vec<SubMsg>,
}

// Test instantiate
#[test_case(
Params {
owner: None,
coin: Asset::Native(Coin::new(1_000_000, "os")),
sender: "creator".to_string(),
expected_error: None,
expected_msgs: vec![SubMsg::new(CosmosMsg::Bank(BankMsg::Send {
to_address: "creator".to_string(),
amount: vec![Coin {
denom: "os".to_string(),
amount: Uint128::new(1000000)
}]
}))]
};
"Happy Path")]
#[test_case(
Params {
owner: None,
coin: Asset::Native(Coin::new(1_000_000, "os")),
sender: "sender".to_string(),
expected_error: Some(ContractError::AdminError(cw_controllers::AdminError::NotAdmin{})),
expected_msgs: vec![]
};
"Unauthorized")]
fn test_withdraw_asset(params: Params) {
// Create mock dependencies
let mut deps = mock_dependencies();

// Create mock info
let info = mock_info(&params.sender, &[]);

// Create mock env with the entry point contract address
let mut env = mock_env();
env.contract.address = Addr::unchecked("entry_point");

// init owner
OWNER
.set(deps.as_mut(), Some(Addr::unchecked("creator")))
.unwrap();

// Call instantiate with the given test parameters
let res = skip_api_entry_point::contract::execute(
deps.as_mut(),
env,
info,
ExecuteMsg::WithdrawAsset {
coin: params.coin,
receiver: None,
},
);

match res {
Ok(res) => {
// Assert the test did not expect an error
assert!(
params.expected_error.is_none(),
"expected test to error with {:?}, but it succeeded",
params.expected_error
);
assert_eq!(
res.messages,
params.expected_msgs
);

// // Get stored ibc transfer adapter contract address
// let stored_ibc_transfer_contract_address = IBC_TRANSFER_CONTRACT_ADDRESS
// .load(deps.as_ref().storage)
// .unwrap();

// // Assert the ibc transfer adapter contract address exists in the blocked contract addresses map
// assert!(BLOCKED_CONTRACT_ADDRESSES
// .has(deps.as_ref().storage, &stored_ibc_transfer_contract_address));

// params.swap_venues.into_iter().for_each(|swap_venue| {
// // Get stored swap venue adapter contract address
// let stored_swap_venue_contract_address = SWAP_VENUE_MAP
// .may_load(deps.as_ref().storage, &swap_venue.name)
// .unwrap()
// .unwrap();

// // Assert the swap venue name exists in the map and that
// // the adapter contract address stored is correct
// assert_eq!(
// &stored_swap_venue_contract_address,
// &Addr::unchecked(&swap_venue.adapter_contract_address)
// );

// // Assert the swap adapter contract address exists in the blocked contract addresses map
// assert!(BLOCKED_CONTRACT_ADDRESSES
// .has(deps.as_ref().storage, &stored_swap_venue_contract_address));
// });
}
Err(err) => {
// Assert the test expected an error
assert!(
params.expected_error.is_some(),
"expected test to succeed, but it errored with {:?}",
err
);

// Assert the error is correct
assert_eq!(err, params.expected_error.unwrap());
}
}
}
4 changes: 4 additions & 0 deletions packages/skip/src/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ pub enum ExecuteMsg {
UniversalSwap {
memo: String,
},
WithdrawAsset {
coin: Asset,
receiver: Option<Addr>,
},
}

/// This structure describes a CW20 hook message.
Expand Down

0 comments on commit 1ec0d2c

Please sign in to comment.