Skip to content

Commit 653c545

Browse files
authored
Merge pull request #18 from oraichain/fix/charge-relayer-fees-round-tripfees
feat: add round trip relayer fees & refactor code
2 parents 5179590 + 04e2347 commit 653c545

File tree

7 files changed

+429
-392
lines changed

7 files changed

+429
-392
lines changed

contracts/cw-ics20-latest/src/contract.rs

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::vec;
33
#[cfg(not(feature = "library"))]
44
use cosmwasm_std::entry_point;
55
use cosmwasm_std::{
6-
from_binary, to_binary, Addr, Binary, Deps, DepsMut, Empty, Env, IbcEndpoint, IbcQuery,
7-
MessageInfo, Order, PortIdResponse, Response, StdError, StdResult, Storage, Uint128,
6+
from_binary, to_binary, Addr, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, IbcEndpoint,
7+
IbcQuery, MessageInfo, Order, PortIdResponse, Response, StdError, StdResult, Storage, Uint128,
88
};
99
use cw2::set_contract_version;
1010
use cw20::{Cw20Coin, Cw20ReceiveMsg};
@@ -14,9 +14,7 @@ use oraiswap::asset::AssetInfo;
1414
use oraiswap::router::RouterController;
1515

1616
use crate::error::ContractError;
17-
use crate::ibc::{
18-
build_ibc_send_packet, collect_fee_msgs, parse_voucher_denom, process_deduct_fee,
19-
};
17+
use crate::ibc::{build_ibc_send_packet, parse_voucher_denom, process_deduct_fee};
2018
use crate::msg::{
2119
AllowMsg, AllowedInfo, AllowedResponse, ChannelResponse, ChannelWithKeyResponse,
2220
ConfigResponse, DeletePairMsg, ExecuteMsg, InitMsg, ListAllowedResponse, ListChannelsResponse,
@@ -26,8 +24,8 @@ use crate::msg::{
2624
use crate::state::{
2725
get_key_ics20_ibc_denom, ics20_denoms, increase_channel_balance, override_channel_balance,
2826
reduce_channel_balance, AllowInfo, Config, MappingMetadata, RelayerFee, ReplyArgs, TokenFee,
29-
ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_REVERSE_STATE, CONFIG, RELAYER_FEE,
30-
RELAYER_FEE_ACCUMULATOR, REPLY_ARGS, SINGLE_STEP_REPLY_ARGS, TOKEN_FEE, TOKEN_FEE_ACCUMULATOR,
27+
ADMIN, ALLOW_LIST, CHANNEL_INFO, CHANNEL_REVERSE_STATE, CONFIG, RELAYER_FEE, REPLY_ARGS,
28+
SINGLE_STEP_REPLY_ARGS, TOKEN_FEE,
3129
};
3230
use cw20_ics20_msg::amount::{convert_local_to_remote, Amount};
3331
use cw_utils::{maybe_addr, nonpayable, one_coin};
@@ -458,7 +456,7 @@ pub fn execute_transfer_back_to_remote_chain(
458456
.ok_or(ContractError::MappingPairNotFound {})?;
459457

460458
// if found mapping, then deduct fee based on mapping
461-
let (new_deducted_amount, token_fee, relayer_fee) = process_deduct_fee(
459+
let fee_data = process_deduct_fee(
462460
deps.storage,
463461
&deps.querier,
464462
deps.api,
@@ -469,6 +467,40 @@ pub fn execute_transfer_back_to_remote_chain(
469467
&config.swap_router_contract,
470468
)?;
471469

470+
let mut cosmos_msgs: Vec<CosmosMsg> = vec![];
471+
if !fee_data.token_fee.is_empty() {
472+
cosmos_msgs.push(
473+
fee_data
474+
.token_fee
475+
.send_amount(config.token_fee_receiver.into_string(), None),
476+
)
477+
}
478+
if !fee_data.relayer_fee.is_empty() {
479+
cosmos_msgs.push(
480+
fee_data
481+
.relayer_fee
482+
.send_amount(config.relayer_fee_receiver.into_string(), None),
483+
)
484+
}
485+
486+
// send response
487+
let token_fee_str = fee_data.token_fee.amount().to_string();
488+
let relayer_fee_str = fee_data.relayer_fee.amount().to_string();
489+
let attributes = vec![
490+
("action", "transfer_back_to_remote_chain"),
491+
("sender", sender.as_str()),
492+
("receiver", &msg.remote_address),
493+
("token_fee", &token_fee_str),
494+
("relayer_fee", &relayer_fee_str),
495+
];
496+
497+
// if our fees have drained the initial amount entirely, then we just get all the fees and that's it
498+
if fee_data.deducted_amount.is_zero() {
499+
return Ok(Response::new()
500+
.add_messages(cosmos_msgs)
501+
.add_attributes(attributes));
502+
}
503+
472504
let ibc_denom = mapping.key;
473505
// ensure the requested channel is registered
474506
if !CHANNEL_INFO.has(deps.storage, &msg.local_channel_id) {
@@ -486,7 +518,7 @@ pub fn execute_transfer_back_to_remote_chain(
486518
let timeout = env.block.time.plus_seconds(timeout_delta);
487519
// need to convert decimal of cw20 to remote decimal before transferring
488520
let amount_remote = convert_local_to_remote(
489-
new_deducted_amount,
521+
fee_data.deducted_amount,
490522
mapping.pair_mapping.remote_decimals,
491523
mapping.pair_mapping.asset_info_decimals,
492524
)?;
@@ -510,30 +542,14 @@ pub fn execute_transfer_back_to_remote_chain(
510542
&msg.local_channel_id,
511543
timeout.into(),
512544
)?;
513-
514-
let mut cosmos_msgs = collect_fee_msgs(
515-
deps.storage,
516-
config.token_fee_receiver.into_string(),
517-
TOKEN_FEE_ACCUMULATOR,
518-
)?;
519-
cosmos_msgs.push(ibc_msg.into());
520-
cosmos_msgs.append(&mut collect_fee_msgs(
521-
deps.storage,
522-
config.relayer_fee_receiver.into_string(),
523-
RELAYER_FEE_ACCUMULATOR,
524-
)?);
525-
526-
// send response
527-
let res = Response::new()
545+
Ok(Response::new()
528546
.add_messages(cosmos_msgs)
529-
.add_attribute("action", "transfer_back_to_remote_chain")
530-
.add_attribute("sender", sender.as_str())
531-
.add_attribute("receiver", &msg.remote_address)
532-
.add_attribute("denom", &ibc_denom)
533-
.add_attribute("amount", &amount_remote.to_string())
534-
.add_attribute("token_fee", token_fee)
535-
.add_attribute("relayer_fee", relayer_fee);
536-
Ok(res)
547+
.add_message(ibc_msg)
548+
.add_attributes(attributes)
549+
.add_attributes(vec![
550+
("denom", &ibc_denom),
551+
("amount", &amount_remote.to_string()),
552+
]))
537553
}
538554

539555
/// The gov contract can allow new contracts, or increase the gas limit on existing contracts.
@@ -642,19 +658,19 @@ pub fn execute_delete_mapping_pair(
642658
}
643659

644660
#[entry_point]
645-
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
661+
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
646662
// we don't need to save anything if migrating from the same version
647-
CONFIG.save(
648-
deps.storage,
649-
&Config {
650-
default_timeout: msg.default_timeout,
651-
default_gas_limit: msg.default_gas_limit,
652-
fee_denom: msg.fee_denom,
653-
swap_router_contract: RouterController(msg.swap_router_contract),
654-
token_fee_receiver: deps.api.addr_validate(&msg.token_fee_receiver)?,
655-
relayer_fee_receiver: deps.api.addr_validate(&msg.relayer_fee_receiver)?,
656-
},
657-
)?;
663+
// CONFIG.save(
664+
// deps.storage,
665+
// &Config {
666+
// default_timeout: msg.default_timeout,
667+
// default_gas_limit: msg.default_gas_limit,
668+
// fee_denom: msg.fee_denom,
669+
// swap_router_contract: RouterController(msg.swap_router_contract),
670+
// token_fee_receiver: deps.api.addr_validate(&msg.token_fee_receiver)?,
671+
// relayer_fee_receiver: deps.api.addr_validate(&msg.relayer_fee_receiver)?,
672+
// },
673+
// )?;
658674
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
659675
Ok(Response::new())
660676
}
@@ -903,7 +919,7 @@ mod test {
903919

904920
use super::*;
905921
use crate::ibc::{handle_packet_refund, ibc_packet_receive, Ics20Packet, REFUND_FAILURE_ID};
906-
use crate::state::{Ratio, TOKEN_FEE_ACCUMULATOR};
922+
use crate::state::Ratio;
907923
use crate::test_helpers::*;
908924

909925
use cosmwasm_std::testing::{mock_env, mock_info};
@@ -1453,15 +1469,6 @@ mod test {
14531469
}
14541470
);
14551471

1456-
// we need to reset fee accumulator because when execute returns error, the test state is still applied
1457-
TOKEN_FEE_ACCUMULATOR
1458-
.save(
1459-
deps.as_mut().storage,
1460-
"cw20:token-addr",
1461-
&Uint128::from(0u64),
1462-
)
1463-
.unwrap();
1464-
14651472
// prepare some mock packets
14661473
let recv_packet =
14671474
mock_receive_packet(remote_channel, local_channel, amount, denom, custom_addr);
@@ -1497,7 +1504,7 @@ mod test {
14971504

14981505
assert_eq!(res.messages[0].gas_limit, None);
14991506
println!("res messages: {:?}", res.messages);
1500-
assert_eq!(2, res.messages.len()); // 2 because it also has deduct fee msg
1507+
assert_eq!(res.messages.len(), 2); // 2 because it also has deduct fee msg
15011508
match res.messages[1].msg.clone() {
15021509
CosmosMsg::Ibc(IbcMsg::SendPacket {
15031510
channel_id,
@@ -1652,15 +1659,6 @@ mod test {
16521659
}
16531660
);
16541661

1655-
// we need to reset fee accumulator because when execute returns error, the test state is still applied
1656-
TOKEN_FEE_ACCUMULATOR
1657-
.save(
1658-
deps.as_mut().storage,
1659-
"cw20:token-addr",
1660-
&Uint128::from(0u64),
1661-
)
1662-
.unwrap();
1663-
16641662
// prepare some mock packets
16651663
let recv_packet =
16661664
mock_receive_packet(remote_channel, local_channel, amount, denom, custom_addr);

contracts/cw-ics20-latest/src/error.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::num::TryFromIntError;
22
use std::string::FromUtf8Error;
33
use thiserror::Error;
44

5-
use cosmwasm_std::StdError;
5+
use cosmwasm_std::{OverflowError, StdError};
66
use cw_controllers::AdminError;
77
use cw_utils::PaymentError;
88

@@ -15,6 +15,9 @@ pub enum ContractError {
1515
#[error("{0}")]
1616
Std(#[from] StdError),
1717

18+
#[error("{0}")]
19+
Overflow(#[from] OverflowError),
20+
1821
#[error("{0}")]
1922
Payment(#[from] PaymentError),
2023

0 commit comments

Comments
 (0)