Skip to content

Fix/re caculate relayer fee #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion contracts/cw-ics20-latest/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ pub fn execute_transfer_back_to_remote_chain(
&msg.remote_address,
&msg.remote_denom,
amount,
mapping.pair_mapping.asset_info_decimals,
&config.swap_router_contract,
)?;

Expand Down
66 changes: 28 additions & 38 deletions contracts/cw-ics20-latest/src/ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ fn handle_ibc_packet_receive_native_remote_chain(
&msg.sender,
&msg.denom,
to_send.clone(),
pair_mapping.asset_info_decimals,
&config.swap_router_contract,
)?;

Expand Down Expand Up @@ -470,10 +469,11 @@ fn handle_ibc_packet_receive_native_remote_chain(
let additional_relayer_fee = deduct_relayer_fee(
storage,
api,
querier,
&destination.receiver,
&remote_destination_denom,
fee_data.token_simulate_amount,
fee_data.token_exchange_rate_with_orai,
destination_asset_info_on_orai.clone(),
&config.swap_router_contract,
)?;

fee_data.relayer_fee = Amount::from_parts(
Expand Down Expand Up @@ -861,36 +861,28 @@ pub fn process_deduct_fee(
remote_sender: &str,
remote_token_denom: &str,
local_amount: Amount, // local amount
decimals: u8,
swap_router_contract: &RouterController,
) -> StdResult<FeeData> {
let local_denom = local_amount.denom();
let (deducted_amount, token_fee) =
deduct_token_fee(storage, remote_token_denom, local_amount.amount())?;
// simulate for relayer fee
let offer_asset_info = denom_to_asset_info(querier, api, &local_amount.raw_denom())?;
let simulate_amount = Uint128::from(10u64.pow((decimals + 1) as u32) as u64); // +1 to make sure the offer amount is large enough to swap successfully
let exchange_rate_with_orai = get_token_price(
querier,
simulate_amount,
swap_router_contract,
offer_asset_info,
);
let ask_asset_info = denom_to_asset_info(querier, api, &local_amount.raw_denom())?;

let relayer_fee = deduct_relayer_fee(
storage,
api,
querier,
remote_sender,
remote_token_denom,
simulate_amount,
exchange_rate_with_orai,
ask_asset_info,
swap_router_contract,
)?;

let mut fee_data = FeeData {
deducted_amount: deducted_amount.checked_sub(relayer_fee).unwrap_or_default(),
token_fee: Amount::from_parts(local_denom.clone(), token_fee),
relayer_fee: Amount::from_parts(local_denom.clone(), relayer_fee),
token_simulate_amount: simulate_amount,
token_exchange_rate_with_orai: exchange_rate_with_orai,
};

// if after token fee, the deducted amount is 0 then we deduct all to token fee
Expand Down Expand Up @@ -927,16 +919,12 @@ pub fn deduct_token_fee(
pub fn deduct_relayer_fee(
storage: &mut dyn Storage,
_api: &dyn Api,
querier: &QuerierWrapper,
remote_address: &str,
remote_token_denom: &str,
simulate_amount: Uint128, // offer amount of token that swaps to ORAI
token_price: Uint128,
ask_asset_info: AssetInfo,
swap_router_contract: &RouterController,
) -> StdResult<Uint128> {
// api.debug(format!("token price: {}", token_price).as_str());
if token_price.is_zero() {
return Ok(Uint128::from(0u64));
}

// this is bech32 prefix of sender from other chains. Should not error because we are in the cosmos ecosystem. Every address should have prefix
// evm case, need to filter remote token denom since prefix is always oraib
let prefix_result = get_prefix_decode_bech32(remote_address);
Expand All @@ -958,13 +946,15 @@ pub fn deduct_relayer_fee(
if relayer_fee.is_none() {
return Ok(Uint128::from(0u64));
}
let relayer_fee = relayer_fee.unwrap();
let required_fee_needed = relayer_fee
.checked_mul(simulate_amount)
.unwrap_or_default()
.checked_div(token_price)
.unwrap_or_default();
Ok(required_fee_needed)

let relayer_fee = get_swap_token_amount_out_from_orai(
querier,
relayer_fee.unwrap(),
swap_router_contract,
ask_asset_info,
);

Ok(relayer_fee)
}

pub fn deduct_fee(token_fee: Ratio, amount: Uint128) -> Uint128 {
Expand All @@ -978,26 +968,26 @@ pub fn deduct_fee(token_fee: Ratio, amount: Uint128) -> Uint128 {
))
}

pub fn get_token_price(
pub fn get_swap_token_amount_out_from_orai(
querier: &QuerierWrapper,
simulate_amount: Uint128,
offer_amount: Uint128,
swap_router_contract: &RouterController,
offer_asset_info: AssetInfo,
ask_asset_info: AssetInfo,
) -> Uint128 {
let orai_asset_info = AssetInfo::NativeToken {
denom: "orai".to_string(),
};
if offer_asset_info.eq(&orai_asset_info) {
return simulate_amount;
if ask_asset_info.eq(&orai_asset_info) {
return offer_amount;
}
let token_price = swap_router_contract
.simulate_swap(
querier,
simulate_amount,
offer_amount,
vec![SwapOperation::OraiSwap {
offer_asset_info,
offer_asset_info: orai_asset_info,
// always swap with orai. If it does not share a pool with ORAI => ignore, no fee
ask_asset_info: orai_asset_info,
ask_asset_info,
}],
)
.map(|data| data.amount)
Expand Down
49 changes: 29 additions & 20 deletions contracts/cw-ics20-latest/src/ibc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ mod test {

use crate::ibc::{
build_ibc_msg, build_swap_msgs, convert_remote_denom_to_evm_prefix, deduct_fee,
deduct_relayer_fee, deduct_token_fee, get_token_price, ibc_packet_receive,
parse_ibc_channel_without_sanity_checks, parse_ibc_denom_without_sanity_checks,
parse_voucher_denom, process_ibc_msg, Ics20Ack, Ics20Packet, FOLLOW_UP_IBC_SEND_FAILURE_ID,
IBC_TRANSFER_NATIVE_ERROR_ID, NATIVE_RECEIVE_ID, SWAP_OPS_FAILURE_ID,
deduct_relayer_fee, deduct_token_fee, get_swap_token_amount_out_from_orai,
ibc_packet_receive, parse_ibc_channel_without_sanity_checks,
parse_ibc_denom_without_sanity_checks, parse_voucher_denom, process_ibc_msg, Ics20Ack,
Ics20Packet, FOLLOW_UP_IBC_SEND_FAILURE_ID, IBC_TRANSFER_NATIVE_ERROR_ID,
NATIVE_RECEIVE_ID, SWAP_OPS_FAILURE_ID,
};
use crate::ibc::{build_swap_operations, get_follow_up_msgs};
use crate::test_helpers::*;
Expand Down Expand Up @@ -1105,16 +1106,20 @@ mod test {
let deps_mut = deps.as_mut();
let token_fee_denom = "cosmos";
let remote_address = "cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n";
let offer_amount = Uint128::from(10u32.pow(0 as u32));
let token_price = Uint128::from(10u64);
let destination_asset_on_orai = AssetInfo::NativeToken {
denom: "orai".to_string(),
};
let swap_router_contract = RouterController("foo".to_string());

// token price empty case. Should return zero fee
let result = deduct_relayer_fee(
deps_mut.storage,
deps_mut.api,
&deps_mut.querier,
remote_address,
token_fee_denom,
offer_amount.clone(),
Uint128::from(0u64),
destination_asset_on_orai.clone(),
&swap_router_contract,
)
.unwrap();
assert_eq!(result, Uint128::from(0u64));
Expand All @@ -1124,10 +1129,11 @@ mod test {
deduct_relayer_fee(
deps_mut.storage,
deps_mut.api,
&deps_mut.querier,
"foobar",
token_fee_denom,
offer_amount.clone(),
token_price,
destination_asset_on_orai.clone(),
&swap_router_contract,
)
.unwrap(),
Uint128::from(0u128)
Expand All @@ -1138,10 +1144,11 @@ mod test {
deduct_relayer_fee(
deps_mut.storage,
deps_mut.api,
&deps_mut.querier,
remote_address,
token_fee_denom,
offer_amount.clone(),
token_price,
destination_asset_on_orai.clone(),
&swap_router_contract,
)
.unwrap(),
Uint128::from(0u64)
Expand All @@ -1160,27 +1167,29 @@ mod test {
deduct_relayer_fee(
deps_mut.storage,
deps_mut.api,
&deps_mut.querier,
"oraib1603j3e4juddh7cuhfquxspl0p0nsun047wz3rl",
"foo0x",
offer_amount.clone(),
token_price,
destination_asset_on_orai.clone(),
&swap_router_contract,
)
.unwrap(),
Uint128::from(100u64)
Uint128::from(1000u64)
);

// normal case with remote address
assert_eq!(
deduct_relayer_fee(
deps_mut.storage,
deps_mut.api,
&deps_mut.querier,
remote_address,
token_fee_denom,
offer_amount.clone(),
token_price,
destination_asset_on_orai,
&swap_router_contract,
)
.unwrap(),
Uint128::from(10u64)
Uint128::from(100u64)
);
}

Expand Down Expand Up @@ -1270,10 +1279,10 @@ mod test {
}

#[test]
fn test_get_token_price_orai_case() {
fn test_get_swap_token_amount_out_from_orai() {
let deps = mock_dependencies();
let simulate_amount = Uint128::from(10u128);
let result = get_token_price(
let result = get_swap_token_amount_out_from_orai(
&deps.as_ref().querier,
simulate_amount,
&RouterController("foo".to_string()),
Expand Down
2 changes: 0 additions & 2 deletions contracts/cw-ics20-latest/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ pub struct FeeData {
pub deducted_amount: Uint128,
pub token_fee: Amount,
pub relayer_fee: Amount,
pub token_simulate_amount: Uint128,
pub token_exchange_rate_with_orai: Uint128,
}

#[cw_serde]
Expand Down