1use ethcontract::tokens::{Bytes, Tokenize};
2use ethcontract::{H160, U256};
3use ethcontract_common::abi::Token::FixedBytes;
4use ethers_core::utils::parse_units;
5
6pub use std::str::FromStr;
7
8use crate::{Address, Bytes32, PoolBalanceOpKind, SwapKind, Variable, IERC20};
9
10#[derive(Clone, Copy, Debug)]
11pub struct PoolId(pub Bytes32);
12impl FromStr for PoolId {
13 type Err = ethcontract::tokens::Error;
14
15 fn from_str(s: &str) -> Result<Self, Self::Err> {
16 let bytes = hexutil::read_hex(s);
17 let bytes = bytes.unwrap();
18 let bytes = Bytes::from_token(FixedBytes(bytes))?;
19
20 Ok(PoolId(bytes))
21 }
22}
23impl From<PoolId> for Bytes32 {
24 fn from(pool_id: PoolId) -> Self {
25 pool_id.0
26 }
27}
28
29#[derive(Debug, Clone, Copy)]
30pub struct UserData(pub &'static str);
31impl From<UserData> for ethcontract::tokens::Bytes<Vec<u8>> {
32 fn from(data: UserData) -> Self {
33 let data = hexutil::read_hex(data.0).unwrap();
34 ethcontract::tokens::Bytes::<Vec<u8>>(data)
35 }
36}
37
38#[derive(Debug, Clone)]
39pub struct FromDecStrErr;
40
41#[derive(Debug, Clone, Copy)]
56pub struct SwapFeePercentage(pub U256);
57impl SwapFeePercentage {
58 pub fn from_human_readable_str(s: &str) -> Result<Self, FromDecStrErr> {
60 let wei = parse_units(s, "ether").unwrap();
61 SwapFeePercentage::from_str(&wei.to_string())
62 }
63}
64impl FromStr for SwapFeePercentage {
65 type Err = FromDecStrErr;
66
67 fn from_str(s: &str) -> Result<Self, Self::Err> {
68 let percentage = U256::from_dec_str(s).unwrap();
69 Ok(SwapFeePercentage(percentage))
70 }
71}
72impl From<SwapFeePercentage> for U256 {
73 fn from(percentage: SwapFeePercentage) -> Self {
74 percentage.0
75 }
76}
77
78type SingleSwapTuple = (
81 ethcontract::Bytes<[u8; 32]>,
82 u8,
83 H160,
84 H160,
85 U256,
86 ethcontract::Bytes<Vec<u8>>,
87);
88#[derive(Debug, Clone)]
90pub struct SingleSwap {
91 pub pool_id: PoolId,
92 pub kind: SwapKind,
93 pub asset_in: Address,
94 pub asset_out: Address,
95 pub amount: U256,
96 pub user_data: ethcontract::tokens::Bytes<Vec<u8>>,
97}
98impl From<SingleSwap> for SingleSwapTuple {
100 fn from(swap: SingleSwap) -> SingleSwapTuple {
101 (
102 swap.pool_id.into(),
103 swap.kind as u8,
104 swap.asset_in,
105 swap.asset_out,
106 swap.amount,
107 swap.user_data,
108 )
109 }
110}
111
112type BatchSwapTuple = (
113 ethcontract::tokens::Bytes<[u8; 32]>,
115 ethcontract::U256,
117 ethcontract::U256,
119 ethcontract::U256,
121 ethcontract::tokens::Bytes<Vec<u8>>,
123);
124
125#[derive(Clone, Debug)]
126pub struct BatchSwapStep {
127 pub pool_id: PoolId,
128 pub asset_in_index: usize,
129 pub asset_out_index: usize,
130 pub amount: U256,
131 pub user_data: UserData,
132}
133impl From<BatchSwapStep> for BatchSwapTuple {
135 fn from(swap_step: BatchSwapStep) -> BatchSwapTuple {
136 (
137 swap_step.pool_id.into(),
138 swap_step.asset_in_index.into(),
139 swap_step.asset_out_index.into(),
140 swap_step.amount,
141 swap_step.user_data.into(),
142 )
143 }
144}
145
146type FundManagementTuple = (
147 ethcontract::Address, bool, ethcontract::Address, bool, );
152pub struct FundManagement {
155 pub sender: ethcontract::Address,
157 pub from_internal_balance: bool,
159 pub recipient: ethcontract::Address,
161 pub to_internal_balance: bool,
164}
165impl From<FundManagement> for FundManagementTuple {
167 fn from(funds: FundManagement) -> FundManagementTuple {
168 (
169 funds.sender,
170 funds.from_internal_balance,
171 funds.recipient,
172 funds.to_internal_balance,
173 )
174 }
175}
176
177pub struct SwapRequest {
178 pub kind: SwapKind,
179 pub token_in: IERC20,
180 pub token_out: IERC20,
181 pub amount: U256,
182
183 pub pool_id: PoolId,
185 pub last_change_block: U256,
186 pub from: Address,
187 pub to: Address,
188 pub user_data: UserData,
189}
190impl From<SwapRequest>
191 for (
192 u8,
193 ethcontract::H160,
194 ethcontract::H160,
195 ethcontract::U256,
196 ethcontract::Bytes<[u8; 32]>,
197 ethcontract::U256,
198 ethcontract::H160,
199 ethcontract::H160,
200 ethcontract::Bytes<std::vec::Vec<u8>>,
201 )
202{
203 fn from(
204 swap_request: SwapRequest,
205 ) -> (
206 u8,
207 ethcontract::H160,
208 ethcontract::H160,
209 ethcontract::U256,
210 ethcontract::Bytes<[u8; 32]>,
211 ethcontract::U256,
212 ethcontract::H160,
213 ethcontract::H160,
214 ethcontract::Bytes<std::vec::Vec<u8>>,
215 ) {
216 let SwapRequest {
217 kind,
218 token_in,
219 token_out,
220 amount,
221 pool_id,
222 last_change_block,
223 from,
224 to,
225 user_data,
226 } = swap_request;
227 (
228 kind as u8,
229 token_in,
230 token_out,
231 amount,
232 pool_id.into(),
233 last_change_block,
234 from,
235 to,
236 user_data.into(),
237 )
238 }
239}
240
241pub struct JoinPoolRequest {
243 pub assets: Vec<Address>,
245 pub max_amounts_in: Vec<U256>,
247 pub user_data: UserData,
249 pub from_internal_balance: bool,
251}
252impl From<JoinPoolRequest>
253 for (
254 Vec<ethcontract::H160>,
255 Vec<ethcontract::U256>,
256 ethcontract::tokens::Bytes<Vec<u8>>,
257 bool,
258 )
259{
260 fn from(
261 request: JoinPoolRequest,
262 ) -> (
263 Vec<ethcontract::H160>,
264 Vec<ethcontract::U256>,
265 ethcontract::tokens::Bytes<Vec<u8>>,
266 bool,
267 ) {
268 let JoinPoolRequest {
269 assets,
270 max_amounts_in,
271 user_data,
272 from_internal_balance,
273 } = request;
274 (
275 assets,
276 max_amounts_in,
277 user_data.into(),
278 from_internal_balance,
279 )
280 }
281}
282
283pub struct ExitPoolRequest {
285 pub assets: Vec<Address>,
287 pub max_amounts_out: Vec<U256>,
289 pub user_data: UserData,
291 pub to_internal_balance: bool,
293}
294impl From<ExitPoolRequest>
295 for (
296 Vec<ethcontract::H160>,
297 Vec<ethcontract::U256>,
298 ethcontract::tokens::Bytes<Vec<u8>>,
299 bool,
300 )
301{
302 fn from(
303 request: ExitPoolRequest,
304 ) -> (
305 Vec<ethcontract::H160>,
306 Vec<ethcontract::U256>,
307 ethcontract::tokens::Bytes<Vec<u8>>,
308 bool,
309 ) {
310 let ExitPoolRequest {
311 assets,
312 max_amounts_out,
313 user_data,
314 to_internal_balance,
315 } = request;
316 (
317 assets,
318 max_amounts_out,
319 user_data.into(),
320 to_internal_balance,
321 )
322 }
323}
324
325pub struct PoolBalanceOp {
327 pub kind: PoolBalanceOpKind,
328 pub pool_id: PoolId,
329 pub token: Address,
330 pub amount: U256,
331}
332impl From<PoolBalanceOp> for (u8, Bytes<[u8; 32]>, Address, U256) {
333 fn from(op: PoolBalanceOp) -> (u8, Bytes<[u8; 32]>, Address, U256) {
334 let PoolBalanceOp {
335 kind,
336 pool_id,
337 token,
338 amount,
339 } = op;
340 (kind as u8, pool_id.into(), token, amount)
341 }
342}
343
344pub struct OracleAverageQuery {
345 pub variable: Variable,
346 pub secs: U256,
347 pub ago: U256,
348}
349impl From<OracleAverageQuery> for (u8, U256, U256) {
350 fn from(query: OracleAverageQuery) -> (u8, U256, U256) {
351 let OracleAverageQuery {
352 variable,
353 secs,
354 ago,
355 } = query;
356 (variable as u8, secs, ago)
357 }
358}
359
360pub struct OracleAccumulatorQuery {
361 pub variable: Variable,
362 pub ago: U256,
363}
364impl From<OracleAccumulatorQuery> for (u8, U256) {
365 fn from(query: OracleAccumulatorQuery) -> (u8, U256) {
366 let OracleAccumulatorQuery { variable, ago } = query;
367 (variable as u8, ago)
368 }
369}