Skip to content

Commit

Permalink
review: gas limit traits
Browse files Browse the repository at this point in the history
  • Loading branch information
laruh committed Sep 26, 2024
1 parent ab0f961 commit b3ed7ba
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 95 deletions.
80 changes: 80 additions & 0 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ pub(crate) use eip1559_gas_fee::FeePerGasEstimated;
use eip1559_gas_fee::{BlocknativeGasApiCaller, FeePerGasSimpleEstimator, GasApiConfig, GasApiProvider,
InfuraGasApiCaller};
pub(crate) mod eth_swap_v2;
use eth_swap_v2::{EthPaymentType, PaymentMethod};

/// https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol
/// Dev chain (195.201.137.5:8565) contract address: 0x83965C539899cC0F918552e5A26915de40ee8852
Expand Down Expand Up @@ -378,6 +379,85 @@ pub struct NftMakerGasLimitV2 {
pub erc1155_maker_refund_secret: u64,
}

pub trait NftGasLimit {
fn nft_gas_limit(&self, contract_type: &ContractType, method: PaymentMethod) -> u64;
}

impl NftGasLimit for EthGasLimitV2 {
fn nft_gas_limit(&self, contract_type: &ContractType, method: PaymentMethod) -> u64 {
match contract_type {
ContractType::Erc1155 => match method {
PaymentMethod::Send => self.nft_maker.erc1155_payment,
PaymentMethod::Spend => self.nft_maker.erc1155_taker_spend,
PaymentMethod::RefundTimelock => self.nft_maker.erc1155_maker_refund_timelock,
PaymentMethod::RefundSecret => self.nft_maker.erc1155_maker_refund_secret,
},
ContractType::Erc721 => match method {
PaymentMethod::Send => self.nft_maker.erc721_payment,
PaymentMethod::Spend => self.nft_maker.erc721_taker_spend,
PaymentMethod::RefundTimelock => self.nft_maker.erc721_maker_refund_timelock,
PaymentMethod::RefundSecret => self.nft_maker.erc721_maker_refund_secret,
},
}
}
}

pub trait GasLimit {
fn gas_limit(
&self,
coin_type: &EthCoinType,
payment_type: EthPaymentType,
method: PaymentMethod,
) -> Result<(Address, u64), String>;
}

impl GasLimit for EthGasLimitV2 {
fn gas_limit(
&self,
coin_type: &EthCoinType,
payment_type: EthPaymentType,
method: PaymentMethod,
) -> Result<(Address, u64), String> {
match coin_type {
EthCoinType::Eth => {
let gas_limit = match payment_type {
EthPaymentType::MakerPayments => match method {
PaymentMethod::Send => self.maker.eth_payment,
PaymentMethod::Spend => self.maker.eth_taker_spend,
PaymentMethod::RefundTimelock => self.maker.eth_maker_refund_timelock,
PaymentMethod::RefundSecret => self.maker.eth_maker_refund_secret,
},
EthPaymentType::TakerPayments => match method {
PaymentMethod::Send => self.taker.eth_payment,
PaymentMethod::Spend => self.taker.eth_maker_spend,
PaymentMethod::RefundTimelock => self.taker.eth_taker_refund_timelock,
PaymentMethod::RefundSecret => self.taker.eth_taker_refund_secret,
},
};
Ok((Address::default(), gas_limit))
},
EthCoinType::Erc20 { token_addr, .. } => {
let gas_limit = match payment_type {
EthPaymentType::MakerPayments => match method {
PaymentMethod::Send => self.maker.erc20_payment,
PaymentMethod::Spend => self.maker.erc20_taker_spend,
PaymentMethod::RefundTimelock => self.maker.erc20_maker_refund_timelock,
PaymentMethod::RefundSecret => self.maker.erc20_maker_refund_secret,
},
EthPaymentType::TakerPayments => match method {
PaymentMethod::Send => self.taker.erc20_payment,
PaymentMethod::Spend => self.taker.erc20_maker_spend,
PaymentMethod::RefundTimelock => self.taker.erc20_taker_refund_timelock,
PaymentMethod::RefundSecret => self.taker.erc20_taker_refund_secret,
},
};
Ok((*token_addr, gas_limit))
},
EthCoinType::Nft { .. } => Err("NFT protocol is not supported for ETH and ERC20 Swaps".to_string()),
}
}
}

impl Default for MakerGasLimitV2 {
fn default() -> Self {
MakerGasLimitV2 {
Expand Down
64 changes: 25 additions & 39 deletions mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{validate_from_to_and_status, validate_payment_args, EthPaymentType, PrepareTxDataError, ZERO_VALUE};
use super::{validate_from_to_and_status, validate_payment_args, EthPaymentType, PaymentMethod, PrepareTxDataError,
ZERO_VALUE};
use crate::coin_errors::{ValidatePaymentError, ValidatePaymentResult};
use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType,
use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, GasLimit,
MakerPaymentStateV2, SignedEthTx, MAKER_SWAP_V2};
use crate::{ParseCoinAssocTypes, RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, SendMakerPaymentArgs,
SpendMakerPaymentArgs, SwapTxTypeWithSecretHash, TransactionErr, ValidateMakerPaymentArgs,
Expand Down Expand Up @@ -181,18 +182,14 @@ impl EthCoin {
&self,
args: RefundMakerPaymentTimelockArgs<'_>,
) -> Result<SignedEthTx, TransactionErr> {
let (token_address, gas_limit) = match &self.coin_type {
EthCoinType::Eth => (Address::default(), self.gas_limit_v2.maker.eth_maker_refund_timelock),
EthCoinType::Erc20 {
platform: _,
token_addr,
} => (*token_addr, self.gas_limit_v2.maker.erc20_maker_refund_timelock),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (token_address, gas_limit) = self
.gas_limit_v2
.gas_limit(
&self.coin_type,
EthPaymentType::MakerPayments,
PaymentMethod::RefundTimelock,
)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let maker_swap_v2_contract = self
.swap_v2_contracts
Expand Down Expand Up @@ -239,18 +236,14 @@ impl EthCoin {
&self,
args: RefundMakerPaymentSecretArgs<'_, Self>,
) -> Result<SignedEthTx, TransactionErr> {
let (token_address, gas_limit) = match &self.coin_type {
EthCoinType::Eth => (Address::default(), self.gas_limit_v2.maker.eth_maker_refund_secret),
EthCoinType::Erc20 {
platform: _,
token_addr,
} => (*token_addr, self.gas_limit_v2.maker.erc20_maker_refund_secret),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (token_address, gas_limit) = self
.gas_limit_v2
.gas_limit(
&self.coin_type,
EthPaymentType::MakerPayments,
PaymentMethod::RefundSecret,
)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let maker_swap_v2_contract = self
.swap_v2_contracts
Expand Down Expand Up @@ -288,18 +281,11 @@ impl EthCoin {
&self,
args: SpendMakerPaymentArgs<'_, Self>,
) -> Result<SignedEthTx, TransactionErr> {
let (token_address, gas_limit) = match &self.coin_type {
EthCoinType::Eth => (Address::default(), U256::from(self.gas_limit_v2.maker.eth_taker_spend)),
EthCoinType::Erc20 {
platform: _,
token_addr,
} => (*token_addr, U256::from(self.gas_limit_v2.maker.erc20_taker_spend)),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (token_address, gas_limit) = self
.gas_limit_v2
.gas_limit(&self.coin_type, EthPaymentType::MakerPayments, PaymentMethod::Spend)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let maker_swap_v2_contract = self
.swap_v2_contracts
.as_ref()
Expand All @@ -312,7 +298,7 @@ impl EthCoin {
U256::from(ZERO_VALUE),
Action::Call(maker_swap_v2_contract),
data,
gas_limit,
U256::from(gas_limit),
)
.compat()
.await
Expand Down
60 changes: 24 additions & 36 deletions mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{check_decoded_length, validate_from_to_and_status, validate_payment_args, validate_payment_state,
EthPaymentType, PrepareTxDataError, ZERO_VALUE};
use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType,
EthPaymentType, PaymentMethod, PrepareTxDataError, ZERO_VALUE};
use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, GasLimit,
ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs,
SignedEthTx, SwapTxTypeWithSecretHash, TakerPaymentStateV2, TransactionErr, ValidateSwapV2TxError,
ValidateSwapV2TxResult, ValidateTakerFundingArgs, TAKER_SWAP_V2};
Expand Down Expand Up @@ -246,18 +246,14 @@ impl EthCoin {
&self,
args: RefundTakerPaymentArgs<'_>,
) -> Result<SignedEthTx, TransactionErr> {
let (token_address, gas_limit) = match &self.coin_type {
EthCoinType::Eth => (Address::default(), self.gas_limit_v2.taker.eth_taker_refund_timelock),
EthCoinType::Erc20 {
platform: _,
token_addr,
} => (*token_addr, self.gas_limit_v2.taker.erc20_taker_refund_timelock),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (token_address, gas_limit) = self
.gas_limit_v2
.gas_limit(
&self.coin_type,
EthPaymentType::TakerPayments,
PaymentMethod::RefundTimelock,
)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let taker_swap_v2_contract = self
.swap_v2_contracts
Expand Down Expand Up @@ -311,18 +307,14 @@ impl EthCoin {
&self,
args: RefundFundingSecretArgs<'_, Self>,
) -> Result<SignedEthTx, TransactionErr> {
let (token_address, gas_limit) = match &self.coin_type {
EthCoinType::Eth => (Address::default(), self.gas_limit_v2.taker.eth_taker_refund_secret),
EthCoinType::Erc20 {
platform: _,
token_addr,
} => (*token_addr, self.gas_limit_v2.taker.erc20_taker_refund_secret),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (token_address, gas_limit) = self
.gas_limit_v2
.gas_limit(
&self.coin_type,
EthPaymentType::TakerPayments,
PaymentMethod::RefundSecret,
)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let taker_swap_v2_contract = self
.swap_v2_contracts
Expand Down Expand Up @@ -396,15 +388,11 @@ impl EthCoin {
gen_args: &GenTakerPaymentSpendArgs<'_, Self>,
secret: &[u8],
) -> Result<SignedEthTx, TransactionErr> {
let gas_limit = match self.coin_type {
EthCoinType::Eth => U256::from(self.gas_limit_v2.taker.eth_maker_spend),
EthCoinType::Erc20 { .. } => U256::from(self.gas_limit_v2.taker.erc20_maker_spend),
EthCoinType::Nft { .. } => {
return Err(TransactionErr::ProtocolNotSupported(ERRL!(
"NFT protocol is not supported for ETH and ERC20 Swaps"
)))
},
};
let (_, gas_limit) = self
.gas_limit_v2
.gas_limit(&self.coin_type, EthPaymentType::TakerPayments, PaymentMethod::Spend)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;

let (taker_swap_v2_contract, approve_func, token_address) = self
.taker_swap_v2_details(TAKER_PAYMENT_APPROVE, TAKER_PAYMENT_APPROVE)
.await?;
Expand Down Expand Up @@ -434,7 +422,7 @@ impl EthCoin {
U256::from(ZERO_VALUE),
Action::Call(taker_swap_v2_contract),
data,
gas_limit,
U256::from(gas_limit),
)
.compat()
.await?;
Expand Down
9 changes: 8 additions & 1 deletion mm2src/coins/eth/eth_swap_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub(crate) mod eth_taker_swap_v2;
/// is provided as part of the input data rather than as an Ether value
pub(crate) const ZERO_VALUE: u32 = 0;

pub(crate) enum EthPaymentType {
pub enum EthPaymentType {
MakerPayments,
TakerPayments,
}
Expand All @@ -32,6 +32,13 @@ impl EthPaymentType {
}
}

pub enum PaymentMethod {
Send,
Spend,
RefundTimelock,
RefundSecret,
}

#[derive(Debug, Display)]
pub(crate) enum ValidatePaymentV2Err {
UnexpectedPaymentState(String),
Expand Down
34 changes: 15 additions & 19 deletions mm2src/coins/eth/nft_swap_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use errors::{Erc721FunctionError, HtlcParamsError};
mod structs;
use structs::{ExpectedHtlcParams, ValidationParams};

use super::ContractType;
use crate::eth::eth_swap_v2::{validate_from_to_and_status, validate_payment_state, EthPaymentType, PaymentStatusErr,
PrepareTxDataError, ZERO_VALUE};
use super::{ContractType, NftGasLimit};
use crate::eth::eth_swap_v2::{validate_from_to_and_status, validate_payment_state, EthPaymentType, PaymentMethod,
PaymentStatusErr, PrepareTxDataError, ZERO_VALUE};
use crate::eth::{decode_contract_call, EthCoin, EthCoinType, MakerPaymentStateV2, SignedEthTx, ERC1155_CONTRACT,
ERC721_CONTRACT, NFT_MAKER_SWAP_V2};
use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs,
Expand All @@ -38,10 +38,9 @@ impl EthCoin {
let htlc_data = try_tx_s!(self.prepare_htlc_data(&args));

let data = try_tx_s!(self.prepare_nft_maker_payment_v2_data(&args, htlc_data).await);
let gas_limit = match args.nft_swap_info.contract_type {
ContractType::Erc1155 => self.gas_limit_v2.nft_maker.erc1155_payment,
ContractType::Erc721 => self.gas_limit_v2.nft_maker.erc721_payment,
};
let gas_limit = self
.gas_limit_v2
.nft_gas_limit(args.nft_swap_info.contract_type, PaymentMethod::Send);
self.sign_and_send_transaction(
ZERO_VALUE.into(),
Action::Call(*args.nft_swap_info.token_address),
Expand Down Expand Up @@ -178,10 +177,9 @@ impl EthCoin {
.await
);
let data = try_tx_s!(self.prepare_spend_nft_maker_v2_data(&args, decoded, htlc_params, state));
let gas_limit = match args.contract_type {
ContractType::Erc1155 => self.gas_limit_v2.nft_maker.erc1155_taker_spend,
ContractType::Erc721 => self.gas_limit_v2.nft_maker.erc721_taker_spend,
};
let gas_limit = self
.gas_limit_v2
.nft_gas_limit(args.contract_type, PaymentMethod::Spend);
self.sign_and_send_transaction(
ZERO_VALUE.into(),
Action::Call(nft_maker_swap_v2_contract),
Expand Down Expand Up @@ -228,10 +226,9 @@ impl EthCoin {
);
let data =
try_tx_s!(self.prepare_refund_nft_maker_payment_v2_timelock(&args, decoded, htlc_params, state));
let gas_limit = match args.contract_type {
ContractType::Erc1155 => self.gas_limit_v2.nft_maker.erc1155_maker_refund_timelock,
ContractType::Erc721 => self.gas_limit_v2.nft_maker.erc721_maker_refund_timelock,
};
let gas_limit = self
.gas_limit_v2
.nft_gas_limit(args.contract_type, PaymentMethod::RefundTimelock);
self.sign_and_send_transaction(
ZERO_VALUE.into(),
Action::Call(nft_maker_swap_v2_contract),
Expand Down Expand Up @@ -279,10 +276,9 @@ impl EthCoin {

let data =
try_tx_s!(self.prepare_refund_nft_maker_payment_v2_secret(&args, decoded, htlc_params, state));
let gas_limit = match args.contract_type {
ContractType::Erc1155 => self.gas_limit_v2.nft_maker.erc1155_maker_refund_secret,
ContractType::Erc721 => self.gas_limit_v2.nft_maker.erc721_maker_refund_secret,
};
let gas_limit = self
.gas_limit_v2
.nft_gas_limit(args.contract_type, PaymentMethod::RefundSecret);
self.sign_and_send_transaction(
ZERO_VALUE.into(),
Action::Call(nft_maker_swap_v2_contract),
Expand Down

0 comments on commit b3ed7ba

Please sign in to comment.