use ethcontract::tokens::{Bytes, Tokenize};
use ethcontract::{H160, U256};
use ethcontract_common::abi::Token::FixedBytes;
use ethers_core::utils::parse_units;
pub use std::str::FromStr;
use crate::{u256, Address, Bytes32, SwapKind, IERC20};
#[derive(Clone, Copy, Debug)]
pub struct PoolId(pub Bytes32);
impl FromStr for PoolId {
type Err = ethcontract::tokens::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = hexutil::read_hex(s);
let bytes = bytes.unwrap();
let bytes = Bytes::from_token(FixedBytes(bytes))?;
Ok(PoolId(bytes))
}
}
impl From<PoolId> for Bytes32 {
fn from(pool_id: PoolId) -> Self {
pool_id.0
}
}
#[derive(Debug, Clone, Copy)]
pub struct UserData(pub &'static str);
impl From<UserData> for ethcontract::tokens::Bytes<Vec<u8>> {
fn from(data: UserData) -> Self {
let data = hexutil::read_hex(data.0).unwrap();
ethcontract::tokens::Bytes::<Vec<u8>>(data)
}
}
#[derive(Debug, Clone, Copy)]
pub struct SwapFeePercentage(pub &'static str);
impl From<SwapFeePercentage> for ethcontract::U256 {
fn from(percentage: SwapFeePercentage) -> Self {
let wei = parse_units(percentage.0, "wei").unwrap();
U256::from_dec_str(&wei.to_string()).unwrap()
}
}
type SingleSwapTuple = (
ethcontract::Bytes<[u8; 32]>,
u8,
H160,
H160,
U256,
ethcontract::Bytes<Vec<u8>>,
);
#[derive(Debug, Clone)]
pub struct SingleSwap {
pub pool_id: PoolId,
pub kind: SwapKind,
pub asset_in: Address,
pub asset_out: Address,
pub amount: U256,
pub user_data: ethcontract::tokens::Bytes<Vec<u8>>,
}
impl From<SingleSwap> for SingleSwapTuple {
fn from(swap: SingleSwap) -> SingleSwapTuple {
(
swap.pool_id.into(),
swap.kind as u8,
swap.asset_in,
swap.asset_out,
swap.amount,
swap.user_data,
)
}
}
type BatchSwapTuple = (
ethcontract::tokens::Bytes<[u8; 32]>,
ethcontract::U256,
ethcontract::U256,
ethcontract::U256,
ethcontract::tokens::Bytes<Vec<u8>>,
);
#[derive(Clone, Debug)]
pub struct BatchSwapStep {
pub pool_id: PoolId,
pub asset_in_index: ethcontract::U256,
pub asset_out_index: ethcontract::U256,
pub amount: ethcontract::U256,
pub user_data: ethcontract::tokens::Bytes<Vec<u8>>,
}
impl BatchSwapStep {
pub fn new(
pool_id: PoolId,
asset_in_index: i32,
asset_out_index: i32,
amount: &str,
user_data: UserData,
) -> Self {
BatchSwapStep {
pool_id: pool_id.into(),
asset_in_index: asset_in_index.into(),
asset_out_index: asset_out_index.into(),
amount: u256!(amount),
user_data: user_data.into(),
}
}
}
impl From<BatchSwapStep> for BatchSwapTuple {
fn from(swap_step: BatchSwapStep) -> BatchSwapTuple {
(
swap_step.pool_id.into(),
swap_step.asset_in_index,
swap_step.asset_out_index,
swap_step.amount,
swap_step.user_data,
)
}
}
type FundManagementTuple = (
ethcontract::Address, bool, ethcontract::Address, bool, );
pub struct FundManagement {
pub sender: ethcontract::Address,
pub from_internal_balance: bool,
pub recipient: ethcontract::Address,
pub to_internal_balance: bool,
}
impl From<FundManagement> for FundManagementTuple {
fn from(funds: FundManagement) -> FundManagementTuple {
(
funds.sender,
funds.from_internal_balance,
funds.recipient,
funds.to_internal_balance,
)
}
}
pub struct SwapRequest {
pub kind: SwapKind,
pub token_in: IERC20,
pub token_out: IERC20,
pub amount: U256,
pub pool_id: Bytes32,
pub last_change_block: U256,
pub from: Address,
pub to: Address,
pub user_data: ethcontract::tokens::Bytes<Vec<u8>>,
}
impl From<SwapRequest>
for (
u8,
ethcontract::H160,
ethcontract::H160,
ethcontract::U256,
ethcontract::Bytes<[u8; 32]>,
ethcontract::U256,
ethcontract::H160,
ethcontract::H160,
ethcontract::Bytes<std::vec::Vec<u8>>,
)
{
fn from(
swap_request: SwapRequest,
) -> (
u8,
ethcontract::H160,
ethcontract::H160,
ethcontract::U256,
ethcontract::Bytes<[u8; 32]>,
ethcontract::U256,
ethcontract::H160,
ethcontract::H160,
ethcontract::Bytes<std::vec::Vec<u8>>,
) {
let SwapRequest {
kind,
token_in,
token_out,
amount,
pool_id,
last_change_block,
from,
to,
user_data,
} = swap_request;
(
kind as u8,
token_in,
token_out,
amount,
pool_id,
last_change_block,
from,
to,
user_data,
)
}
}
pub struct JoinPoolRequest {
pub assets: Vec<Address>,
pub max_amounts_in: Vec<U256>,
pub user_data: UserData,
pub from_internal_balance: bool,
}
impl From<JoinPoolRequest>
for (
Vec<ethcontract::H160>,
Vec<ethcontract::U256>,
ethcontract::tokens::Bytes<Vec<u8>>,
bool,
)
{
fn from(
request: JoinPoolRequest,
) -> (
Vec<ethcontract::H160>,
Vec<ethcontract::U256>,
ethcontract::tokens::Bytes<Vec<u8>>,
bool,
) {
let JoinPoolRequest {
assets,
max_amounts_in,
user_data,
from_internal_balance,
} = request;
(
assets.into(),
max_amounts_in,
user_data.into(),
from_internal_balance,
)
}
}
pub struct ExitPoolRequest {
pub assets: Vec<Address>,
pub max_amounts_out: Vec<U256>,
pub user_data: UserData,
pub to_internal_balance: bool,
}
impl From<ExitPoolRequest>
for (
Vec<ethcontract::H160>,
Vec<ethcontract::U256>,
ethcontract::tokens::Bytes<Vec<u8>>,
bool,
)
{
fn from(
request: ExitPoolRequest,
) -> (
Vec<ethcontract::H160>,
Vec<ethcontract::U256>,
ethcontract::tokens::Bytes<Vec<u8>>,
bool,
) {
let ExitPoolRequest {
assets,
max_amounts_out,
user_data,
to_internal_balance,
} = request;
(
assets.into(),
max_amounts_out,
user_data.into(),
to_internal_balance,
)
}
}