Skip to content

Commit

Permalink
add native withdraws to assetManager for archway
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonAndell committed Nov 2, 2023
1 parent 6cc7551 commit e5f14b0
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 2 deletions.
2 changes: 2 additions & 0 deletions contracts/core-contracts/cw-asset-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ crate-type = ["cdylib", "rlib"]
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
default = ["archway"]
archway = []

[package.metadata.scripts]
optimize = """docker run --rm -v "$(pwd)":/code \
Expand Down
176 changes: 174 additions & 2 deletions contracts/core-contracts/cw-asset-manager/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use cosmwasm_std::{
use cw2::set_contract_version;
use cw20::{AllowanceResponse, Cw20ExecuteMsg, Cw20QueryMsg};

use cw_common::asset_manager_msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use cw_common::asset_manager_msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use cw_common::network_address::IconAddressValidation;
use cw_common::network_address::NetworkAddress;
use cw_common::x_call_msg::{GetNetworkAddress, XCallMsg};
Expand Down Expand Up @@ -57,7 +57,14 @@ pub fn execute(
ExecuteMsg::HandleCallMessage { from, data } => {
exec::handle_xcall_msg(deps, env, info, from, data)
}

ExecuteMsg::ConfigureNative {
native_token_address,
native_token_manager,
} => {
let owner = OWNER.load(deps.storage).map_err(ContractError::Std)?;
ensure_eq!(owner, info.sender, ContractError::OnlyOwner);
exec::setup_native_token(deps, native_token_address, native_token_manager)
}
ExecuteMsg::Deposit {
token_address,
amount,
Expand Down Expand Up @@ -160,6 +167,25 @@ mod exec {
Ok(Response::default())
}

pub fn setup_native_token(
deps: DepsMut,
native_token_address: String,
native_token_manager: String,
) -> Result<Response, ContractError> {
let token_addr = deps
.api
.addr_validate(&native_token_address)
.map_err(ContractError::Std)?;
let token_manager_addr = deps
.api
.addr_validate(&native_token_manager)
.map_err(ContractError::Std)?;
NATIVE_TOKEN_ADDRESS.save(deps.storage, &token_addr)?;
NATIVE_TOKEN_MANAGER.save(deps.storage, &token_manager_addr)?;

Ok(Response::default())
}

#[allow(clippy::too_many_arguments)]
pub fn deposit_cw20_tokens(
deps: DepsMut,
Expand Down Expand Up @@ -307,6 +333,19 @@ mod exec {

transfer_tokens(deps, account, token_address, amount)?
}

DecodedStruct::WithdrawNativeTo(data_struct) => {
let icon_am = ICON_ASSET_MANAGER.load(deps.storage)?;
if from != icon_am.to_string() {
return Err(ContractError::OnlyIconAssetManager {});

Check warning on line 340 in contracts/core-contracts/cw-asset-manager/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/contract.rs#L340

Added line #L340 was not covered by tests
}

let token_address = data_struct.token_address;
let account = data_struct.user_address;
let amount = Uint128::from(data_struct.amount);

swap_to_native(deps, account, token_address, amount)?
}
};

Ok(res)
Expand Down Expand Up @@ -341,6 +380,68 @@ mod exec {
};
Ok(Response::new().add_submessage(sub_msg))
}

#[cfg(feature = "archway")]
fn swap_to_native(
deps: DepsMut,
account: String,
token_address: String,
amount: Uint128,
) -> Result<Response, ContractError> {
use crate::external::{ConfigResponse, Cw20HookMsg, StakingQueryMsg};

deps.api.addr_validate(&account)?;
deps.api.addr_validate(&token_address)?;
let query_msg = &StakingQueryMsg::ConfigInfo {};
let manager = NATIVE_TOKEN_MANAGER.load(deps.storage)?;
let query_resp: ConfigResponse = deps
.querier
.query_wasm_smart::<ConfigResponse>(manager.clone(), &query_msg)?;
let swap_contract = query_resp.swap_contract_addr;

let hook = &Cw20HookMsg::Swap {
belief_price: None,
max_spread: None,
to: Some(account.clone()),
};
let transfer_msg = &Cw20ExecuteMsg::Send {
contract: swap_contract.clone(),
amount,
msg: to_binary(hook)?,
};

let execute_msg: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: token_address.clone(),
msg: to_binary(transfer_msg)?,
funds: vec![],
});

let sub_msg = SubMsg {
id: SUCCESS_REPLY_MSG,
msg: execute_msg,
gas_limit: None,
reply_on: cosmwasm_std::ReplyOn::Never,
};
Ok(Response::new().add_submessage(sub_msg))
}

#[cfg(not(any(feature = "archway")))]
fn swap_to_native(
deps: DepsMut,
account: String,
token_address: String,
amount: Uint128,
) -> Result<Response, ContractError> {
transfer_tokens(deps, account, token_address, amount)
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)
.map_err(ContractError::Std)?;

Check warning on line 442 in contracts/core-contracts/cw-asset-manager/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/contract.rs#L441-L442

Added lines #L441 - L442 were not covered by tests

Ok(Response::default().add_attribute("migrate", "successful"))

Check warning on line 444 in contracts/core-contracts/cw-asset-manager/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/contract.rs#L444

Added line #L444 was not covered by tests
}

#[cfg_attr(not(feature = "library"), entry_point)]
Expand Down Expand Up @@ -640,6 +741,77 @@ mod tests {
assert!(result.is_err());
}

#[cfg(feature = "archway")]
#[test]
fn test_withdraw_native_archway() {
use cw_common::xcall_data_types::WithdrawNativeTo;

use crate::external::ConfigResponse;

let (mut deps, env, info, _) = test_setup();
let mocked_xcall_info = mock_info("xcall", &[]);

let staking = "staking";
let swap = "swap";
let token = "token1";
let account = "account1";

deps.querier.update_wasm(|r: &WasmQuery| match r {
WasmQuery::Smart {
contract_addr: _,
msg: _,
} => {
SystemResult::Ok(ContractResult::Ok(
to_binary(&ConfigResponse{
admin: "".to_string(),
pause_admin: "".to_string(),
bond_denom: "".to_string(),
liquid_token_addr: "".to_string(),
swap_contract_addr: swap.to_string(),
treasury_contract_addr: "".to_string(),
team_wallet_addr: "".to_string(),
commission_percentage: 1,
team_percentage: 1,
liquidity_percentage: 1,
delegations: vec![],
contract_state: false,
}).unwrap(),
))
}
_ => todo!(),

Check warning on line 781 in contracts/core-contracts/cw-asset-manager/src/contract.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/contract.rs#L781

Added line #L781 was not covered by tests
});

let resp = execute(
deps.as_mut(),
env.clone(),
info,
ExecuteMsg::ConfigureNative {
native_token_address: token.to_string(),
native_token_manager: staking.to_string()
},
);
assert!(resp.is_ok());

let am_nw = "0x01.icon/cxc2d01de5013778d71d99f985e4e2ff3a9b48a66c";
let withdraw_msg = WithdrawNativeTo {
token_address: token.to_string(),
amount: 1000,
user_address: account.to_string(),
};

let exe_msg = ExecuteMsg::HandleCallMessage {
from: am_nw.to_string(),
data: withdraw_msg.rlp_bytes().to_vec(),
};
let resp = execute(
deps.as_mut(),
env.clone(),
mocked_xcall_info.clone(),
exe_msg,
);
assert!(resp.is_ok());
}

#[test]
fn test_configure_network() {
//verify configuration updates from owner side
Expand Down
54 changes: 54 additions & 0 deletions contracts/core-contracts/cw-asset-manager/src/external.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Decimal;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[cw_serde]
pub enum StakingQueryMsg {
ConfigInfo {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ConfigResponse {
/// Should be multi-sig, is able to update the config
pub admin: String,
/// Should be single-sig, is able to pause the contract
pub pause_admin: String,
/// This is the denomination we can stake (and only one we accept for payments)
pub bond_denom: String,
/// Liquid token address
pub liquid_token_addr: String,
/// Swap contract address
pub swap_contract_addr: String,
/// Liquid Treasury contract address
pub treasury_contract_addr: String,
/// Team wallet address
pub team_wallet_addr: String,
/// percentage of commission taken off of staking rewards
pub commission_percentage: u16,
/// percentage of rewards for the team
pub team_percentage: u16,
/// percentage of rewards for the liquidity providers
pub liquidity_percentage: u16,
/// Delegations preferences for a whitelist of validators, each validator has a delegation percentage
pub delegations: Vec<DelegationPercentage>,
/// contract state (active/paused)
pub contract_state: bool,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]

Check warning on line 39 in contracts/core-contracts/cw-asset-manager/src/external.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/external.rs#L39

Added line #L39 was not covered by tests
pub struct DelegationPercentage {
pub validator: String,
pub percentage: u16,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Cw20HookMsg {
/// Sell a given amount of asset
Swap {
belief_price: Option<Decimal>,
max_spread: Option<Decimal>,
to: Option<String>,
},
}
25 changes: 25 additions & 0 deletions contracts/core-contracts/cw-asset-manager/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::error::ContractError;
#[derive(Debug)]
pub enum DecodedStruct {
WithdrawTo(WithdrawTo),
WithdrawNativeTo(WithdrawTo),
DepositRevert(DepositRevert),
}

Expand Down Expand Up @@ -45,6 +46,30 @@ pub fn decode_encoded_bytes(data: &[u8]) -> Result<(&str, DecodedStruct), Contra
Ok(("WithdrawTo", DecodedStruct::WithdrawTo(withdraw_to)))
}

"WithdrawNativeTo" => {
if rlp.item_count()? != 4 {
return Err(DecoderError::RlpInvalidLength.into());

Check warning on line 51 in contracts/core-contracts/cw-asset-manager/src/helpers.rs

View check run for this annotation

Codecov / codecov/patch

contracts/core-contracts/cw-asset-manager/src/helpers.rs#L51

Added line #L51 was not covered by tests
}

// Extract the fields
let token: String = rlp.val_at(1)?;
let user_address: String = rlp.val_at(2)?;
let amount: u128 = rlp.val_at(3)?;

// Create a new WithdrawTo instance
let withdraw_to = WithdrawTo {
token_address: token,
user_address,
amount,
};

// Return the decoded struct as an OK variant
Ok((
"WithdrawNativeTo",
DecodedStruct::WithdrawNativeTo(withdraw_to),
))
}

"DepositRevert" => {
if rlp.item_count()? != 4 {
return Err(DecoderError::RlpInvalidLength.into());
Expand Down
1 change: 1 addition & 0 deletions contracts/core-contracts/cw-asset-manager/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod constants;
pub mod contract;
mod error;
pub mod external;
pub mod helpers;
pub mod state;
pub use crate::error::ContractError;
3 changes: 3 additions & 0 deletions contracts/core-contracts/cw-asset-manager/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ pub const NID: Item<NetId> = Item::new("network_id");
pub const ICON_ASSET_MANAGER: Item<NetworkAddress> =
Item::new("icon_asset_manager_network_address");
pub const ICON_NET_ID: Item<NetId> = Item::new("icon_asset_manager_network_id");

pub const NATIVE_TOKEN_ADDRESS: Item<Addr> = Item::new("native_token_address");
pub const NATIVE_TOKEN_MANAGER: Item<Addr> = Item::new("native_token_manager");
8 changes: 8 additions & 0 deletions contracts/cw-common/src/asset_manager_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ pub enum ExecuteMsg {
destination_asset_manager: String,
},

ConfigureNative {
native_token_address: String,
native_token_manager: String,
},

HandleCallMessage {
from: String,
data: Vec<u8>,
Expand Down Expand Up @@ -58,3 +63,6 @@ pub struct NetIdResponse {
pub x_call_nid: String, //NetID
pub icon_nid: String, //NetID
}

#[cw_serde]

Check warning on line 67 in contracts/cw-common/src/asset_manager_msg.rs

View check run for this annotation

Codecov / codecov/patch

contracts/cw-common/src/asset_manager_msg.rs#L67

Added line #L67 was not covered by tests
pub struct MigrateMsg {}
18 changes: 18 additions & 0 deletions contracts/cw-common/src/xcall_data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ pub struct WithdrawTo {
pub amount: u128,
}

#[cw_serde]

Check warning on line 30 in contracts/cw-common/src/xcall_data_types.rs

View check run for this annotation

Codecov / codecov/patch

contracts/cw-common/src/xcall_data_types.rs#L30

Added line #L30 was not covered by tests
pub struct WithdrawNativeTo {
pub token_address: String,
pub user_address: String,
pub amount: u128,
}

//for testing
impl Encodable for Deposit {
//specify the encoding logic for struct's fields so that rlp_bytes() can alo use
Expand Down Expand Up @@ -65,6 +72,17 @@ impl Encodable for WithdrawTo {
}
}

impl Encodable for WithdrawNativeTo {
fn rlp_append(&self, s: &mut RlpStream) {
let method = "WithdrawNativeTo".to_string();
s.begin_list(4)
.append(&method)
.append(&self.token_address)
.append(&self.user_address)
.append(&self.amount);
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit e5f14b0

Please sign in to comment.