Account
0.197779 APT
Balance
router
22 entry functions | Bytecode: 12.72 KB
Code
The source code is plain text uploaded by the deployer, which can be different from the actual bytecode.
1module multi_router::router {
2 use std::option;
3 use std::signer;
4 use std::vector;
5
6 use aries::fa_to_coin_wrapper;
7
8 use aptos_framework::aptos_account;
9 use aptos_framework::coin;
10 use aptos_framework::coin::Coin;
11 use aptos_token::token::{Self, Token};
12
13 use liquidswap::coin_helper;
14
15 // LS v0 deps.
16 use liquidswap::liquidity_pool as liquidity_pool_v0;
17 use liquidswap::router_v2 as router_ls_v0;
18 use liquidswap_lp::lp_coin::LP as LPv0;
19
20 // LS v0.5 deps.
21 use liquidswap_v05::liquidity_pool as liquidity_pool_v05;
22 use liquidswap_v05::router as router_ls_v05;
23 use liquidswap_lp_v05::lp_coin::LP as LPv05;
24
25 // LS v1 deps.
26 use liquidswap_v1::pool as liquidity_pool_v1;
27 use liquidswap_v1::router as router_ls_v1;
28
29 /// Insufficient amount.
30 const ERR_INSUFFICIENT_AMOUNT: u64 = 4000;
31
32 /// Wrong versions array length.
33 const ERR_WRONG_VERSION_ARRAY_LENGTH: u64 = 4001;
34
35 /// Wrong version.
36 const ERR_WRONG_VERSION: u64 = 4002;
37
38 /// Not enough output coins in pool to perform swap (LS V1).
39 const ERR_NOT_ENOUGH_OUTPUT_COINS_TO_PERFORM_SWAP: u64 = 4003;
40
41 /// Wrong coin_out_min_vals array length.
42 const ERR_WRONG_COIN_MIN_ARRAY_LENGTH: u64 = 4004;
43
44 /// Wrong coin_out_vals array length.
45 const ERR_WRONG_COIN_OUT_ARRAY_LENGTH: u64 = 4005;
46
47 /// Wrong swaps_x_for_y array length.
48 const ERR_WRONG_SWAP_ARRAY_LENGTH: u64 = 4006;
49
50
51 // Versions.
52 const LS_V0: u8 = 0;
53 const LS_V05: u8 = 5;
54 const LS_V1: u8 = 10;
55
56 /// Reserved curve for V1.
57 struct CurveV1 {}
58
59 /// Reserved bin step for V0 and V05.
60 struct BinStepV0V05 {}
61
62 //
63 // Swap exact coin for coin
64 //
65
66 /// Swap coin `X` -> `Y`.
67 /// * `coin_in_val` - amount of coin X to swap.
68 /// * `coin_out_min_vals` - slippage for internal routes.
69 /// * `ls_versions` - which version of LS to use, see constants above.
70 /// * `swaps_x_for_y` - swap x for y or y for x.
71 ///
72 /// Result coins `Y` would be deposited to account.
73 public entry fun swap_exact_coin_for_coin_x1<X, Y, C0, BS0>(
74 account: &signer,
75 coin_in_val: u64,
76 coin_out_min_vals: vector<u64>,
77 ls_versions: vector<u8>,
78 swaps_x_for_y: vector<bool>
79 ) {
80 assert!(vector::length(&coin_out_min_vals) == 1, ERR_WRONG_COIN_MIN_ARRAY_LENGTH);
81 assert!(vector::length(&ls_versions) == 1, ERR_WRONG_VERSION_ARRAY_LENGTH);
82 assert!(vector::length(&swaps_x_for_y) == 1, ERR_WRONG_SWAP_ARRAY_LENGTH);
83
84 let account_addr = signer::address_of(account);
85 let coin_in = coin::withdraw<X>(account, coin_in_val);
86
87 let version = *vector::borrow(&ls_versions, 0);
88 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
89 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
90
91 let coin_mid =
92 swap_exact_in_inner<X, Y, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
93
94 assert!(coin::value(&coin_mid) >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
95
96 // Deposit result.
97 aptos_account::deposit_coins(account_addr, coin_mid);
98 }
99
100 /// Fungible asset swap coin `X` -> `Y`.
101 /// * `coin_in_val` - amount of coin X to swap.
102 /// * `coin_out_min_vals` - slippage for internal routes.
103 /// * `ls_versions` - which version of LS to use, see constants above.
104 /// * `swaps_x_for_y` - swap x for y or y for x.
105 ///
106 /// Result coins `Y` would be deposited to account.
107 public entry fun fa_swap_exact_coin_for_coin_x1<X, Y, C0, BS0>(
108 account: &signer,
109 coin_in_val: u64,
110 coin_out_min_vals: vector<u64>,
111 ls_versions: vector<u8>,
112 swaps_x_for_y: vector<bool>
113 ) {
114 assert!(vector::length(&ls_versions) == 1, ERR_WRONG_VERSION_ARRAY_LENGTH);
115
116 // Wrap FA into coins if needed.
117 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
118 coin::withdraw<X>(account, coin_in_val)
119 } else {
120 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_val)
121 };
122
123 let version = *vector::borrow(&ls_versions, 0);
124 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
125 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
126
127 let coin_mid =
128 swap_exact_in_inner<X, Y, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
129
130 // Unwrap coins into FA if needed.
131 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
132 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
133 } else {
134 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
135 };
136 }
137
138 /// Swap coin `X` -> `Z` -> `Y`.
139 /// * `coin_in_val` - amount of coin X to swap.
140 /// * `coin_out_min_vals` - slippage for internal routes.
141 /// * `ls_versions` - which version of LS to use, see constants above.
142 /// * `swaps_x_for_y` - swap x for y or y for x.
143 ///
144 /// Result coins `Y` would be deposited to account.
145 public entry fun swap_exact_coin_for_coin_x2<X, Z, Y, C0, C1, BS0, BS1>(
146 account: &signer,
147 coin_in_val: u64,
148 coin_out_min_vals: vector<u64>,
149 ls_versions: vector<u8>,
150 swaps_x_for_y: vector<bool>
151 ) {
152 assert!(vector::length(&coin_out_min_vals) == 2, ERR_WRONG_COIN_MIN_ARRAY_LENGTH);
153 assert!(vector::length(&ls_versions) == 2, ERR_WRONG_VERSION_ARRAY_LENGTH);
154 assert!(vector::length(&swaps_x_for_y) == 2, ERR_WRONG_SWAP_ARRAY_LENGTH);
155
156 let account_addr = signer::address_of(account);
157
158 let coin_in = coin::withdraw<X>(account, coin_in_val);
159
160 // First route.
161 let version = *vector::borrow(&ls_versions, 0);
162 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
163 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
164 let coin_mid =
165 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
166
167 // Second route.
168 let version = *vector::borrow(&ls_versions, 1);
169 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
170 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
171 let coin_mid =
172 swap_exact_in_inner<Z, Y, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
173
174 assert!(coin::value(&coin_mid) >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
175
176 // Deposit result.
177 aptos_account::deposit_coins(account_addr, coin_mid);
178 }
179
180 /// Fungible asset swap coin `X` -> `Z` -> `Y`.
181 /// * `coin_in_val` - amount of coin X to swap.
182 /// * `coin_out_min_vals` - slippage for internal routes.
183 /// * `ls_versions` - which version of LS to use, see constants above.
184 /// * `swaps_x_for_y` - swap x for y or y for x.
185 ///
186 /// Result coins `Y` would be deposited to account.
187 public entry fun fa_swap_exact_coin_for_coin_x2<X, Z, Y, C0, C1, BS0, BS1>(
188 account: &signer,
189 coin_in_val: u64,
190 coin_out_min_vals: vector<u64>,
191 ls_versions: vector<u8>,
192 swaps_x_for_y: vector<bool>
193 ) {
194 assert!(vector::length(&ls_versions) == 2, ERR_WRONG_VERSION_ARRAY_LENGTH);
195
196 // Wrap FA into coins if needed.
197 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
198 coin::withdraw<X>(account, coin_in_val)
199 } else {
200 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_val)
201 };
202
203 // First route.
204 let version = *vector::borrow(&ls_versions, 0);
205 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
206 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
207 let coin_mid =
208 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
209
210 // Second route.
211 let version = *vector::borrow(&ls_versions, 1);
212 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
213 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
214 let coin_mid =
215 swap_exact_in_inner<Z, Y, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
216
217 // Unwrap coins into FA if needed.
218 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
219 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
220 } else {
221 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
222 };
223 }
224
225 /// Swap coin `X` -> `Z` -> `W` -> `Y`.
226 /// * `coin_in_val` - amount of coin X to swap.
227 /// * `coin_out_min_vals` - slippage for internal routes.
228 /// * `ls_versions` - which version of LS to use, see constants above.
229 /// * `swaps_x_for_y` - swap x for y or y for x.
230 ///
231 /// Result coins `Y` would be deposited to account.
232 public entry fun swap_exact_coin_for_coin_x3<X, Z, W, Y, C0, C1, C2, BS0, BS1, BS2>(
233 account: &signer,
234 coin_in_val: u64,
235 coin_out_min_vals: vector<u64>,
236 ls_versions: vector<u8>,
237 swaps_x_for_y: vector<bool>
238 ) {
239 assert!(vector::length(&coin_out_min_vals) == 3, ERR_WRONG_COIN_MIN_ARRAY_LENGTH);
240 assert!(vector::length(&ls_versions) == 3, ERR_WRONG_VERSION_ARRAY_LENGTH);
241 assert!(vector::length(&swaps_x_for_y) == 3, ERR_WRONG_SWAP_ARRAY_LENGTH);
242
243 let account_addr = signer::address_of(account);
244
245 let coin_in = coin::withdraw<X>(account, coin_in_val);
246
247 // First route.
248 let version = *vector::borrow(&ls_versions, 0);
249 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
250 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
251 let coin_mid =
252 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
253
254 // Second route.
255 let version = *vector::borrow(&ls_versions, 1);
256 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
257 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
258 let coin_mid =
259 swap_exact_in_inner<Z, W, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
260
261 // Third route.
262 let version = *vector::borrow(&ls_versions, 2);
263 let coin_out_min = *vector::borrow(&coin_out_min_vals, 2);
264 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
265 let coin_mid =
266 swap_exact_in_inner<W, Y, C2, BS2>(coin_mid, coin_out_min, version, x_for_y);
267
268 assert!(coin::value(&coin_mid) >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
269
270 // Deposit result.
271 aptos_account::deposit_coins(account_addr, coin_mid);
272 }
273
274 /// Fungible asset swap coin `X` -> `Z` -> `W` -> `Y`.
275 /// * `coin_in_val` - amount of coin X to swap.
276 /// * `coin_out_min_vals` - slippage for internal routes.
277 /// * `ls_versions` - which version of LS to use, see constants above.
278 /// * `swaps_x_for_y` - swap x for y or y for x.
279 ///
280 /// Result coins `Y` would be deposited to account.
281 public entry fun fa_swap_exact_coin_for_coin_x3<X, Z, W, Y, C0, C1, C2, BS0, BS1, BS2>(
282 account: &signer,
283 coin_in_val: u64,
284 coin_out_min_vals: vector<u64>,
285 ls_versions: vector<u8>,
286 swaps_x_for_y: vector<bool>
287 ) {
288 assert!(vector::length(&ls_versions) == 3, ERR_WRONG_VERSION_ARRAY_LENGTH);
289
290 // Wrap FA into coins if needed.
291 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
292 coin::withdraw<X>(account, coin_in_val)
293 } else {
294 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_val)
295 };
296
297 // First route.
298 let version = *vector::borrow(&ls_versions, 0);
299 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
300 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
301 let coin_mid =
302 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
303
304 // Second route.
305 let version = *vector::borrow(&ls_versions, 1);
306 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
307 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
308 let coin_mid =
309 swap_exact_in_inner<Z, W, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
310
311 // Third route.
312 let version = *vector::borrow(&ls_versions, 2);
313 let coin_out_min = *vector::borrow(&coin_out_min_vals, 2);
314 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
315 let coin_mid =
316 swap_exact_in_inner<W, Y, C2, BS2>(coin_mid, coin_out_min, version, x_for_y);
317
318 // Unwrap coins into FA if needed.
319 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
320 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
321 } else {
322 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
323 };
324 }
325
326 /// Swap coin `X` -> `Z` -> `W` -> `V` -> `Y`.
327 /// * `coin_in_val` - amount of coin X to swap.
328 /// * `coin_out_min_vals` - slippage for internal routes.
329 /// * `ls_versions` - which version of LS to use, see constants above.
330 /// * `swaps_x_for_y` - swap x for y or y for x.
331 ///
332 /// Result coins `Y` would be deposited to account.
333 public entry fun swap_exact_coin_for_coin_x4<X, Z, W, V, Y, C0, C1, C2, C3, BS0, BS1, BS2, BS3>(
334 account: &signer,
335 coin_in_val: u64,
336 coin_out_min_vals: vector<u64>,
337 ls_versions: vector<u8>,
338 swaps_x_for_y: vector<bool>
339 ) {
340 assert!(vector::length(&coin_out_min_vals) == 4, ERR_WRONG_COIN_MIN_ARRAY_LENGTH);
341 assert!(vector::length(&ls_versions) == 4, ERR_WRONG_VERSION_ARRAY_LENGTH);
342 assert!(vector::length(&swaps_x_for_y) == 4, ERR_WRONG_SWAP_ARRAY_LENGTH);
343
344 let account_addr = signer::address_of(account);
345
346 let coin_in = coin::withdraw<X>(account, coin_in_val);
347
348 // First route.
349 let version = *vector::borrow(&ls_versions, 0);
350 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
351 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
352 let coin_mid =
353 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
354
355 // Second route.
356 let version = *vector::borrow(&ls_versions, 1);
357 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
358 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
359 let coin_mid =
360 swap_exact_in_inner<Z, W, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
361
362 // Third route.
363 let version = *vector::borrow(&ls_versions, 2);
364 let coin_out_min = *vector::borrow(&coin_out_min_vals, 2);
365 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
366 let coin_mid =
367 swap_exact_in_inner<W, V, C2, BS2>(coin_mid, coin_out_min, version, x_for_y);
368
369 // Fourth route.
370 let version = *vector::borrow(&ls_versions, 3);
371 let coin_out_min = *vector::borrow(&coin_out_min_vals, 3);
372 let x_for_y = *vector::borrow(&swaps_x_for_y, 3);
373 let coin_mid =
374 swap_exact_in_inner<V, Y, C3, BS3>(coin_mid, coin_out_min, version, x_for_y);
375
376 assert!(coin::value(&coin_mid) >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
377
378 // Deposit result.
379 aptos_account::deposit_coins(account_addr, coin_mid);
380 }
381
382 /// Fungible asset swap coin `X` -> `Z` -> `W` -> `V` -> `Y`.
383 /// * `coin_in_val` - amount of coin X to swap.
384 /// * `coin_out_min_vals` - slippage for internal routes.
385 /// * `ls_versions` - which version of LS to use, see constants above.
386 /// * `swaps_x_for_y` - swap x for y or y for x.
387 ///
388 /// Result coins `Y` would be deposited to account.
389 public entry fun fa_swap_exact_coin_for_coin_x4<X, Z, W, V, Y, C0, C1, C2, C3, BS0, BS1, BS2, BS3>(
390 account: &signer,
391 coin_in_val: u64,
392 coin_out_min_vals: vector<u64>,
393 ls_versions: vector<u8>,
394 swaps_x_for_y: vector<bool>
395 ) {
396 assert!(vector::length(&ls_versions) == 4, ERR_WRONG_VERSION_ARRAY_LENGTH);
397
398 // Wrap FA into coins if needed.
399 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
400 coin::withdraw<X>(account, coin_in_val)
401 } else {
402 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_val)
403 };
404
405 // First route.
406 let version = *vector::borrow(&ls_versions, 0);
407 let coin_out_min = *vector::borrow(&coin_out_min_vals, 0);
408 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
409 let coin_mid =
410 swap_exact_in_inner<X, Z, C0, BS0>(coin_in, coin_out_min, version, x_for_y);
411
412 // Second route.
413 let version = *vector::borrow(&ls_versions, 1);
414 let coin_out_min = *vector::borrow(&coin_out_min_vals, 1);
415 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
416 let coin_mid =
417 swap_exact_in_inner<Z, W, C1, BS1>(coin_mid, coin_out_min, version, x_for_y);
418
419 // Third route.
420 let version = *vector::borrow(&ls_versions, 2);
421 let coin_out_min = *vector::borrow(&coin_out_min_vals, 2);
422 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
423 let coin_mid =
424 swap_exact_in_inner<W, V, C2, BS2>(coin_mid, coin_out_min, version, x_for_y);
425
426 // Fourth route.
427 let version = *vector::borrow(&ls_versions, 3);
428 let coin_out_min = *vector::borrow(&coin_out_min_vals, 3);
429 let x_for_y = *vector::borrow(&swaps_x_for_y, 3);
430 let coin_mid =
431 swap_exact_in_inner<V, Y, C3, BS3>(coin_mid, coin_out_min, version, x_for_y);
432
433 // Unwrap coins into FA if needed.
434 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
435 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
436 } else {
437 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
438 };
439 }
440
441 //
442 // Swap coin for exact coin
443 //
444
445 /// Swap coin `X` -> `Y`.
446 /// * `coin_in_max_val` - max amount of coin X to swap.
447 /// * `coin_out_vals` - amount of coins that must be received during the swap.
448 /// * `ls_versions` - which version of LS to use, see constants above.
449 /// * `swaps_x_for_y` - swap x for y or y for x.
450 ///
451 /// Result coins `Y` would be deposited to account.
452 public entry fun swap_coin_for_exact_coin_x1<X, Y, C0, BS0>(
453 account: &signer,
454 coin_in_max_val: u64,
455 coin_out_vals: vector<u64>,
456 ls_versions: vector<u8>,
457 swaps_x_for_y: vector<bool>
458 ) {
459 assert!(vector::length(&coin_out_vals) == 1, ERR_WRONG_COIN_OUT_ARRAY_LENGTH);
460 assert!(vector::length(&ls_versions) == 1, ERR_WRONG_VERSION_ARRAY_LENGTH);
461 assert!(vector::length(&swaps_x_for_y) == 1, ERR_WRONG_SWAP_ARRAY_LENGTH);
462
463 let account_addr = signer::address_of(account);
464
465 let coin_out = *vector::borrow(&coin_out_vals, 0);
466 let version = *vector::borrow(&ls_versions, 0);
467 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
468 let coin_in_req_val = get_amount_in<X, Y, C0, BS0>(coin_out, version, x_for_y);
469 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
470
471 let coin_in = coin::withdraw<X>(account, coin_in_req_val);
472
473 let coin_mid =
474 swap_exact_out_inner<X, Y, C0, BS0>(coin_in, coin_out, version, x_for_y);
475
476 assert!(coin::value(&coin_mid) >= coin_out, ERR_INSUFFICIENT_AMOUNT);
477
478 // Deposit result.
479 aptos_account::deposit_coins(account_addr, coin_mid);
480 }
481
482 /// Fungible asset swap coin `X` -> `Y`.
483 /// * `coin_in_max_val` - max amount of coin X to swap.
484 /// * `coin_out_vals` - amount of coins that must be received during the swap.
485 /// * `ls_versions` - which version of LS to use, see constants above.
486 /// * `swaps_x_for_y` - swap x for y or y for x.
487 ///
488 /// Result coins `Y` would be deposited to account.
489 public entry fun fa_swap_coin_for_exact_coin_x1<X, Y, C0, BS0>(
490 account: &signer,
491 coin_in_max_val: u64,
492 coin_out_vals: vector<u64>,
493 ls_versions: vector<u8>,
494 swaps_x_for_y: vector<bool>
495 ) {
496 assert!(vector::length(&ls_versions) == 1, ERR_WRONG_VERSION_ARRAY_LENGTH);
497
498 let coin_out = *vector::borrow(&coin_out_vals, 0);
499 let version = *vector::borrow(&ls_versions, 0);
500 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
501 let coin_in_req_val = get_amount_in<X, Y, C0, BS0>(coin_out, version, x_for_y);
502 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
503
504 // Wrap FA into coins if needed.
505 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
506 coin::withdraw<X>(account, coin_in_req_val)
507 } else {
508 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_req_val)
509 };
510
511 let coin_mid =
512 swap_exact_out_inner<X, Y, C0, BS0>(coin_in, coin_out, version, x_for_y);
513
514 // Unwrap coins into FA if needed.
515 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
516 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
517 } else {
518 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
519 };
520 }
521
522 /// Swap coin `X` -> `Z` -> `Y`.
523 /// * `coin_in_max_val` - max amount of coin X to swap.
524 /// * `coin_out_vals` - amount of coins that must be received during the swap.
525 /// * `ls_versions` - which version of LS to use, see constants above.
526 /// * `swaps_x_for_y` - swap x for y or y for x.
527 ///
528 /// Result coins `Y` would be deposited to account.
529 public entry fun swap_coin_for_exact_coin_x2<X, Z, Y, C0, C1, BS0, BS1>(
530 account: &signer,
531 coin_in_max_val: u64,
532 coin_out_vals: vector<u64>,
533 ls_versions: vector<u8>,
534 swaps_x_for_y: vector<bool>
535 ) {
536 assert!(vector::length(&coin_out_vals) == 2, ERR_WRONG_COIN_OUT_ARRAY_LENGTH);
537 assert!(vector::length(&ls_versions) == 2, ERR_WRONG_VERSION_ARRAY_LENGTH);
538 assert!(vector::length(&swaps_x_for_y) == 2, ERR_WRONG_SWAP_ARRAY_LENGTH);
539
540 let account_addr = signer::address_of(account);
541
542 // First route.
543 let coin_out = *vector::borrow(&coin_out_vals, 0);
544 let version = *vector::borrow(&ls_versions, 0);
545 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
546 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
547 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
548
549 let coin_in = coin::withdraw<X>(account, coin_in_req_val);
550
551 let coin_mid =
552 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
553
554 // Second route.
555 let coin_out = *vector::borrow(&coin_out_vals, 1);
556 let version = *vector::borrow(&ls_versions, 1);
557 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
558 let coin_in_req_val = get_amount_in<Z, Y, C1, BS1>(coin_out, version, x_for_y);
559 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
560
561 let coin_mid =
562 swap_exact_out_inner<Z, Y, C1, BS1>(coin_mid, coin_out, version, x_for_y);
563
564 assert!(coin::value(&coin_mid) >= coin_out, ERR_INSUFFICIENT_AMOUNT);
565
566 // Deposit result.
567 aptos_account::deposit_coins(account_addr, coin_mid);
568 }
569
570 /// Fungible asset swap coin `X` -> `Z` -> `Y`.
571 /// * `coin_in_max_val` - max amount of coin X to swap.
572 /// * `coin_out_vals` - amount of coins that must be received during the swap.
573 /// * `ls_versions` - which version of LS to use, see constants above.
574 /// * `swaps_x_for_y` - swap x for y or y for x.
575 ///
576 /// Result coins `Y` would be deposited to account.
577 public entry fun fa_swap_coin_for_exact_coin_x2<X, Z, Y, C0, C1, BS0, BS1>(
578 account: &signer,
579 coin_in_max_val: u64,
580 coin_out_vals: vector<u64>,
581 ls_versions: vector<u8>,
582 swaps_x_for_y: vector<bool>
583 ) {
584 assert!(vector::length(&ls_versions) == 2, ERR_WRONG_VERSION_ARRAY_LENGTH);
585
586 let account_addr = signer::address_of(account);
587
588 // First route.
589 let coin_out = *vector::borrow(&coin_out_vals, 0);
590 let version = *vector::borrow(&ls_versions, 0);
591 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
592 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
593 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
594
595 // Wrap FA into coins if needed.
596 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
597 coin::withdraw<X>(account, coin_in_req_val)
598 } else {
599 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_req_val)
600 };
601
602 let coin_mid =
603 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
604
605 // Second route.
606 let coin_out = *vector::borrow(&coin_out_vals, 1);
607 let version = *vector::borrow(&ls_versions, 1);
608 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
609 let coin_in_req_val = get_amount_in<Z, Y, C1, BS1>(coin_out, version, x_for_y);
610 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
611
612 let coin_mid =
613 swap_exact_out_inner<Z, Y, C1, BS1>(coin_mid, coin_out, version, x_for_y);
614
615 // Unwrap coins into FA if needed.
616 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
617 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
618 } else {
619 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
620 };
621 }
622
623 /// Swap coin `X` -> `Z` -> `W` -> `Y`.
624 /// * `coin_in_max_val` - max amount of coin X to swap.
625 /// * `coin_out_vals` - amount of coins that must be received during the swap.
626 /// * `ls_versions` - which version of LS to use, see constants above.
627 /// * `swaps_x_for_y` - swap x for y or y for x.
628 ///
629 /// Result coins `Y` would be deposited to account.
630 public entry fun swap_coin_for_exact_coin_x3<X, Z, W, Y, C0, C1, C2, BS0, BS1, BS2>(
631 account: &signer,
632 coin_in_max_val: u64,
633 coin_out_vals: vector<u64>,
634 ls_versions: vector<u8>,
635 swaps_x_for_y: vector<bool>
636 ) {
637 assert!(vector::length(&coin_out_vals) == 3, ERR_WRONG_COIN_OUT_ARRAY_LENGTH);
638 assert!(vector::length(&ls_versions) == 3, ERR_WRONG_VERSION_ARRAY_LENGTH);
639 assert!(vector::length(&swaps_x_for_y) == 3, ERR_WRONG_SWAP_ARRAY_LENGTH);
640
641 let account_addr = signer::address_of(account);
642
643 // First route.
644 let coin_out = *vector::borrow(&coin_out_vals, 0);
645 let version = *vector::borrow(&ls_versions, 0);
646 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
647 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
648 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
649
650 let coin_in = coin::withdraw<X>(account, coin_in_req_val);
651
652 let coin_mid =
653 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
654
655 // Second route.
656 let coin_out = *vector::borrow(&coin_out_vals, 1);
657 let version = *vector::borrow(&ls_versions, 1);
658 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
659 let coin_in_req_val = get_amount_in<Z, W, C1, BS1>(coin_out, version, x_for_y);
660 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
661
662 let coin_mid =
663 swap_exact_out_inner<Z, W, C1, BS1>(coin_mid, coin_out, version, x_for_y);
664
665 // Third route.
666 let coin_out = *vector::borrow(&coin_out_vals, 2);
667 let version = *vector::borrow(&ls_versions, 2);
668 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
669 let coin_in_req_val = get_amount_in<W, Y, C2, BS2>(coin_out, version, x_for_y);
670 coin_mid = check_coin_in<W>(coin_mid, coin_in_req_val, account_addr);
671
672 let coin_mid =
673 swap_exact_out_inner<W, Y, C2, BS2>(coin_mid, coin_out, version, x_for_y);
674
675 assert!(coin::value(&coin_mid) >= coin_out, ERR_INSUFFICIENT_AMOUNT);
676
677 // Deposit result.
678 aptos_account::deposit_coins(account_addr, coin_mid);
679 }
680
681 /// Fungible asset swap coin `X` -> `Z` -> `W` -> `Y`.
682 /// * `coin_in_max_val` - max amount of coin X to swap.
683 /// * `coin_out_vals` - amount of coins that must be received during the swap.
684 /// * `ls_versions` - which version of LS to use, see constants above.
685 /// * `swaps_x_for_y` - swap x for y or y for x.
686 ///
687 /// Result coins `Y` would be deposited to account.
688 public entry fun fa_swap_coin_for_exact_coin_x3<X, Z, W, Y, C0, C1, C2, BS0, BS1, BS2>(
689 account: &signer,
690 coin_in_max_val: u64,
691 coin_out_vals: vector<u64>,
692 ls_versions: vector<u8>,
693 swaps_x_for_y: vector<bool>
694 ) {
695 assert!(vector::length(&ls_versions) == 3, ERR_WRONG_VERSION_ARRAY_LENGTH);
696
697 let account_addr = signer::address_of(account);
698
699 // First route.
700 let coin_out = *vector::borrow(&coin_out_vals, 0);
701 let version = *vector::borrow(&ls_versions, 0);
702 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
703 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
704 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
705
706 // Wrap FA into coins if needed.
707 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
708 coin::withdraw<X>(account, coin_in_req_val)
709 } else {
710 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_req_val)
711 };
712
713 let coin_mid =
714 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
715
716 // Second route.
717 let coin_out = *vector::borrow(&coin_out_vals, 1);
718 let version = *vector::borrow(&ls_versions, 1);
719 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
720 let coin_in_req_val = get_amount_in<Z, W, C1, BS1>(coin_out, version, x_for_y);
721 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
722
723 let coin_mid =
724 swap_exact_out_inner<Z, W, C1, BS1>(coin_mid, coin_out, version, x_for_y);
725
726 // Third route.
727 let coin_out = *vector::borrow(&coin_out_vals, 2);
728 let version = *vector::borrow(&ls_versions, 2);
729 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
730 let coin_in_req_val = get_amount_in<W, Y, C2, BS2>(coin_out, version, x_for_y);
731 coin_mid = check_coin_in<W>(coin_mid, coin_in_req_val, account_addr);
732
733 let coin_mid =
734 swap_exact_out_inner<W, Y, C2, BS2>(coin_mid, coin_out, version, x_for_y);
735
736 // Unwrap coins into FA if needed.
737 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
738 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
739 } else {
740 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
741 };
742 }
743
744 /// Swap coin `X` -> `Z` -> `W` -> `V` -> `Y`.
745 /// * `coin_in_max_val` - max amount of coin X to swap.
746 /// * `coin_out_vals` - amount of coins that must be received during the swap.
747 /// * `ls_versions` - which version of LS to use, see constants above.
748 /// * `swaps_x_for_y` - swap x for y or y for x.
749 ///
750 /// Result coins `Y` would be deposited to account.
751 public entry fun swap_coin_for_exact_coin_x4<X, Z, W, V, Y, C0, C1, C2, C3, BS0, BS1, BS2, BS3>(
752 account: &signer,
753 coin_in_max_val: u64,
754 coin_out_vals: vector<u64>,
755 ls_versions: vector<u8>,
756 swaps_x_for_y: vector<bool>
757 ) {
758 assert!(vector::length(&coin_out_vals) == 4, ERR_WRONG_COIN_OUT_ARRAY_LENGTH);
759 assert!(vector::length(&ls_versions) == 4, ERR_WRONG_VERSION_ARRAY_LENGTH);
760 assert!(vector::length(&swaps_x_for_y) == 4, ERR_WRONG_SWAP_ARRAY_LENGTH);
761
762 let account_addr = signer::address_of(account);
763
764 // First route.
765 let coin_out = *vector::borrow(&coin_out_vals, 0);
766 let version = *vector::borrow(&ls_versions, 0);
767 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
768 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
769 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
770
771 let coin_in = coin::withdraw<X>(account, coin_in_req_val);
772
773 let coin_mid =
774 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
775
776 // Second route.
777 let coin_out = *vector::borrow(&coin_out_vals, 1);
778 let version = *vector::borrow(&ls_versions, 1);
779 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
780 let coin_in_req_val = get_amount_in<Z, W, C1, BS1>(coin_out, version, x_for_y);
781 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
782
783 let coin_mid =
784 swap_exact_out_inner<Z, W, C1, BS1>(coin_mid, coin_out, version, x_for_y);
785
786 // Third route.
787 let coin_out = *vector::borrow(&coin_out_vals, 2);
788 let version = *vector::borrow(&ls_versions, 2);
789 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
790 let coin_in_req_val = get_amount_in<W, V, C2, BS2>(coin_out, version, x_for_y);
791 coin_mid = check_coin_in<W>(coin_mid, coin_in_req_val, account_addr);
792
793 let coin_mid =
794 swap_exact_out_inner<W, V, C2, BS2>(coin_mid, coin_out, version, x_for_y);
795
796 // Fourth route.
797 let coin_out = *vector::borrow(&coin_out_vals, 3);
798 let version = *vector::borrow(&ls_versions, 3);
799 let x_for_y = *vector::borrow(&swaps_x_for_y, 3);
800 let coin_in_req_val = get_amount_in<V, Y, C3, BS3>(coin_out, version, x_for_y);
801 coin_mid = check_coin_in<V>(coin_mid, coin_in_req_val, account_addr);
802
803 let coin_mid =
804 swap_exact_out_inner<V, Y, C3, BS3>(coin_mid, coin_out, version, x_for_y);
805
806 assert!(coin::value(&coin_mid) >= coin_out, ERR_INSUFFICIENT_AMOUNT);
807
808 // Deposit result.
809 aptos_account::deposit_coins(account_addr, coin_mid);
810 }
811
812 /// Fungible asset swap coin `X` -> `Z` -> `W` -> `V` -> `Y`.
813 /// * `coin_in_max_val` - max amount of coin X to swap.
814 /// * `coin_out_vals` - amount of coins that must be received during the swap.
815 /// * `ls_versions` - which version of LS to use, see constants above.
816 /// * `swaps_x_for_y` - swap x for y or y for x.
817 ///
818 /// Result coins `Y` would be deposited to account.
819 public entry fun fa_swap_coin_for_exact_coin_x4<X, Z, W, V, Y, C0, C1, C2, C3, BS0, BS1, BS2, BS3>(
820 account: &signer,
821 coin_in_max_val: u64,
822 coin_out_vals: vector<u64>,
823 ls_versions: vector<u8>,
824 swaps_x_for_y: vector<bool>
825 ) {
826 assert!(vector::length(&ls_versions) == 4, ERR_WRONG_VERSION_ARRAY_LENGTH);
827
828 let account_addr = signer::address_of(account);
829
830 // First route.
831 let coin_out = *vector::borrow(&coin_out_vals, 0);
832 let version = *vector::borrow(&ls_versions, 0);
833 let x_for_y = *vector::borrow(&swaps_x_for_y, 0);
834 let coin_in_req_val = get_amount_in<X, Z, C0, BS0>(coin_out, version, x_for_y);
835 assert!(coin_in_req_val <= coin_in_max_val, ERR_INSUFFICIENT_AMOUNT);
836
837 // Wrap FA into coins if needed.
838 let coin_in = if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
839 coin::withdraw<X>(account, coin_in_req_val)
840 } else {
841 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_in_req_val)
842 };
843
844 let coin_mid =
845 swap_exact_out_inner<X, Z, C0, BS0>(coin_in, coin_out, version, x_for_y);
846
847 // Second route.
848 let coin_out = *vector::borrow(&coin_out_vals, 1);
849 let version = *vector::borrow(&ls_versions, 1);
850 let x_for_y = *vector::borrow(&swaps_x_for_y, 1);
851 let coin_in_req_val = get_amount_in<Z, W, C1, BS1>(coin_out, version, x_for_y);
852 coin_mid = check_coin_in<Z>(coin_mid, coin_in_req_val, account_addr);
853
854 let coin_mid =
855 swap_exact_out_inner<Z, W, C1, BS1>(coin_mid, coin_out, version, x_for_y);
856
857 // Third route.
858 let coin_out = *vector::borrow(&coin_out_vals, 2);
859 let version = *vector::borrow(&ls_versions, 2);
860 let x_for_y = *vector::borrow(&swaps_x_for_y, 2);
861 let coin_in_req_val = get_amount_in<W, V, C2, BS2>(coin_out, version, x_for_y);
862 coin_mid = check_coin_in<W>(coin_mid, coin_in_req_val, account_addr);
863
864 let coin_mid =
865 swap_exact_out_inner<W, V, C2, BS2>(coin_mid, coin_out, version, x_for_y);
866
867 // Fourth route.
868 let coin_out = *vector::borrow(&coin_out_vals, 3);
869 let version = *vector::borrow(&ls_versions, 3);
870 let x_for_y = *vector::borrow(&swaps_x_for_y, 3);
871 let coin_in_req_val = get_amount_in<V, Y, C3, BS3>(coin_out, version, x_for_y);
872 coin_mid = check_coin_in<V>(coin_mid, coin_in_req_val, account_addr);
873
874 let coin_mid =
875 swap_exact_out_inner<V, Y, C3, BS3>(coin_mid, coin_out, version, x_for_y);
876
877 // Unwrap coins into FA if needed.
878 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
879 aptos_account::deposit_coins(signer::address_of(account), coin_mid);
880 } else {
881 fa_to_coin_wrapper::coin_to_fa(coin_mid, account);
882 };
883 }
884
885 /// Swap exact amount_in inner.
886 /// * `coin_in` - `From` coins to swap.
887 /// * `coin_out_min` - minimum amount of coins to get back.
888 /// * `version` - version of LS to execute swap.
889 /// * `x_for_y` - swap x for y or y for x.
890 ///
891 /// Returns the amount out.
892 fun swap_exact_in_inner<From, To, Curve, BinStep>(
893 coin_in: Coin<From>,
894 coin_out_min: u64,
895 version: u8,
896 x_for_y: bool
897 ): Coin<To> {
898 let coin_in_val = coin::value(&coin_in);
899 let coin_mid;
900
901 if (version == LS_V0) {
902 let expected_out = router_ls_v0::get_amount_out<From, To, Curve>(coin_in_val);
903 assert!(expected_out >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
904 coin_mid = swap_ls_v0<From, To, Curve>(coin_in, expected_out);
905 } else if (version == LS_V05) {
906 let expected_out = router_ls_v05::get_amount_out<From, To, Curve>(coin_in_val);
907 assert!(expected_out >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
908 coin_mid = swap_ls_v05<From, To, Curve>(coin_in, expected_out);
909 } else if (version == LS_V1) {
910 coin_mid = swap_ls_v1<From, To, BinStep>(coin_in, x_for_y);
911 assert!(coin::value(&coin_mid) >= coin_out_min, ERR_INSUFFICIENT_AMOUNT);
912 } else {
913 abort ERR_WRONG_VERSION
914 };
915
916 coin_mid
917 }
918
919 /// Swap exact amount_out inner.
920 /// * `coin_in` - `From` coins to swap.
921 /// * `coin_out` - amount of coins to get back.
922 /// * `version` - version of LS to execute swap.
923 /// * `x_for_y` - swap x for y or y for x.
924 ///
925 /// Returns the amount out.
926 fun swap_exact_out_inner<From, To, Curve, BinStep>(
927 coin_in: Coin<From>,
928 coin_out: u64,
929 version: u8,
930 x_for_y: bool
931 ): Coin<To> {
932 let coin_mid;
933
934 if (version == LS_V0) {
935 coin_mid = swap_ls_v0<From, To, Curve>(coin_in, coin_out);
936 } else if (version == LS_V05) {
937 coin_mid = swap_ls_v05<From, To, Curve>(coin_in, coin_out);
938 } else if (version == LS_V1) {
939 coin_mid = swap_ls_v1<From, To, BinStep>(coin_in, x_for_y);
940 } else {
941 abort ERR_WRONG_VERSION
942 };
943
944 coin_mid
945 }
946
947 /// Simulates a swap in.
948 /// * `coin_out` - expected amount of out coins.
949 /// * `version` - version of LS to execute swap.
950 /// * `x_for_y` - swap x for y or y for x.
951 ///
952 /// Returns the amount in.
953 inline fun get_amount_in<From, To, Curve, BinStep>(coin_out: u64, version: u8, x_for_y: bool): u64 {
954 let coin_in;
955 if (version == LS_V0) {
956 coin_in = router_ls_v0::get_amount_in<From, To, Curve>(coin_out)
957 } else if (version == LS_V05) {
958 coin_in = router_ls_v05::get_amount_in<From, To, Curve>(coin_out)
959 } else if (version == LS_V1) {
960 let amount_out_left;
961 if (x_for_y) {
962 (coin_in, amount_out_left, _) = liquidity_pool_v1::get_amount_in<From, To, BinStep>(coin_out, !x_for_y);
963 } else {
964 (coin_in, amount_out_left, _) = liquidity_pool_v1::get_amount_in<To, From, BinStep>(coin_out, !x_for_y);
965 };
966 assert!(amount_out_left == 0, ERR_NOT_ENOUGH_OUTPUT_COINS_TO_PERFORM_SWAP);
967 } else {
968 abort ERR_WRONG_VERSION
969 };
970 coin_in
971 }
972
973 /// Checks the amount of coins after swap.
974 /// * `coin_in` - coin.
975 /// * `coin_in_req_val` - amount of coins needed for the next swap.
976 ///
977 /// Returns coin.
978 inline fun check_coin_in<X>(coin_in: Coin<X>, coin_in_req_val: u64, account_addr: address): Coin<X> {
979 let coin_in_val = coin::value(&coin_in);
980 assert!(coin_in_req_val <= coin_in_val, ERR_INSUFFICIENT_AMOUNT);
981
982 if (coin_in_req_val == coin_in_val) {
983 coin_in
984 } else {
985 let coin_in_leftovers = coin::extract(&mut coin_in, coin_in_val - coin_in_req_val);
986 aptos_account::deposit_coins(account_addr, coin_in_leftovers);
987 coin_in
988 }
989 }
990
991 /// Excute liquidswap V0 swap.
992 /// * `coin_in` - coins to swap for another.
993 /// * `expected_out` - amount of out coins to get.
994 inline fun swap_ls_v0<From, To, Curve>(
995 coin_in: Coin<From>,
996 expected_out: u64,
997 ): Coin<To> {
998 let (coin, zero);
999
1000 if (coin_helper::is_sorted<From, To>()) {
1001 (zero, coin) = liquidity_pool_v0::swap<From, To, Curve>(coin_in, 0, coin::zero(), expected_out);
1002 } else {
1003 (coin, zero) = liquidity_pool_v0::swap<To, From, Curve>(coin::zero(), expected_out, coin_in, 0);
1004 };
1005
1006 coin::destroy_zero(zero);
1007 coin
1008 }
1009
1010 /// Excute liquidswap V0.5 swap.
1011 /// * `coin_in` - coins to swap for another.
1012 /// * `expected_out` - minimum amount to get out.
1013 inline fun swap_ls_v05<From, To, Curve>(
1014 coin_in: Coin<From>,
1015 expected_out: u64
1016 ): Coin<To> {
1017 let (coin, zero);
1018
1019 if (coin_helper::is_sorted<From, To>()) {
1020 (zero, coin) = liquidity_pool_v05::swap<From, To, Curve>(coin_in, 0, coin::zero(), expected_out);
1021 } else {
1022 (coin, zero) = liquidity_pool_v05::swap<To, From, Curve>(coin::zero(), expected_out, coin_in, 0);
1023 };
1024
1025 coin::destroy_zero(zero);
1026 coin
1027 }
1028
1029 /// Excute liquidswap V1 swap.
1030 /// * `coin_in` - coins to swap for another.
1031 /// * `swap_x_for_y` - swap x for y or y for x.
1032 inline fun swap_ls_v1<From, To, BinStep>(
1033 coin_in: Coin<From>,
1034 x_for_y: bool
1035 ): Coin<To> {
1036 if (x_for_y) {
1037 liquidity_pool_v1::swap_x_for_y<From, To, BinStep>(coin_in)
1038 } else {
1039 liquidity_pool_v1::swap_y_for_x<To, From, BinStep>(coin_in)
1040 }
1041 }
1042
1043 //
1044 // Add liquidity
1045 //
1046
1047 /// Add new liquidity into v0 pool `X`/`Y` and get liquidity coin `LP`.
1048 /// * `coin_x_val` - amount of coin `X` to add as liquidity.
1049 /// * `coin_x_val_min` - minimum amount of coin `X` to add as liquidity (slippage).
1050 /// * `coin_y_val` - minimum amount of coin `Y` to add as liquidity.
1051 /// * `coin_y_val_min` - minimum amount of coin `Y` to add as liquidity (slippage).
1052 ///
1053 /// Note: X, Y generic coin parameters must be sorted.
1054 public entry fun add_liquidity_v0<X, Y, Curve>(
1055 account: &signer,
1056 coin_x_val: u64,
1057 coin_x_val_min: u64,
1058 coin_y_val: u64,
1059 coin_y_val_min: u64,
1060 ) {
1061 let is_wrapped_x = fa_to_coin_wrapper::is_fa_wrapped_coin<X>();
1062 let is_wrapped_y = fa_to_coin_wrapper::is_fa_wrapped_coin<Y>();
1063
1064 let coin_x = if (!is_wrapped_x) {
1065 coin::withdraw<X>(account, coin_x_val)
1066 } else {
1067 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_x_val)
1068 };
1069
1070 let coin_y = if (!is_wrapped_y) {
1071 coin::withdraw<Y>(account, coin_y_val)
1072 } else {
1073 fa_to_coin_wrapper::fa_to_coin<Y>(account, coin_y_val)
1074 };
1075
1076 let (coin_x_remainder, coin_y_remainder, lp_coins) =
1077 router_ls_v0::add_liquidity<X, Y, Curve>(
1078 coin_x,
1079 coin_x_val_min,
1080 coin_y,
1081 coin_y_val_min,
1082 );
1083
1084 let account_addr = signer::address_of(account);
1085
1086 if (!is_wrapped_x) {
1087 coin::deposit(account_addr, coin_x_remainder);
1088 } else {
1089 fa_to_coin_wrapper::coin_to_fa(coin_x_remainder, account);
1090 };
1091
1092 if (!is_wrapped_y) {
1093 coin::deposit(account_addr, coin_y_remainder);
1094 } else {
1095 fa_to_coin_wrapper::coin_to_fa(coin_y_remainder, account);
1096 };
1097 aptos_account::deposit_coins(account_addr, lp_coins);
1098 }
1099
1100 /// Add new liquidity into v0.5 pool `X`/`Y` and get liquidity coin `LP`.
1101 /// * `coin_x_val` - amount of coin `X` to add as liquidity.
1102 /// * `coin_x_val_min` - minimum amount of coin `X` to add as liquidity (slippage).
1103 /// * `coin_y_val` - minimum amount of coin `Y` to add as liquidity.
1104 /// * `coin_y_val_min` - minimum amount of coin `Y` to add as liquidity (slippage).
1105 ///
1106 /// Note: X, Y generic coin parameters must be sorted.
1107 public entry fun add_liquidity_v05<X, Y, Curve>(
1108 account: &signer,
1109 coin_x_val: u64,
1110 coin_x_val_min: u64,
1111 coin_y_val: u64,
1112 coin_y_val_min: u64,
1113 ) {
1114 let is_wrapped_x = fa_to_coin_wrapper::is_fa_wrapped_coin<X>();
1115 let is_wrapped_y = fa_to_coin_wrapper::is_fa_wrapped_coin<Y>();
1116
1117 let coin_x = if (!is_wrapped_x) {
1118 coin::withdraw<X>(account, coin_x_val)
1119 } else {
1120 fa_to_coin_wrapper::fa_to_coin<X>(account, coin_x_val)
1121 };
1122
1123 let coin_y = if (!is_wrapped_y) {
1124 coin::withdraw<Y>(account, coin_y_val)
1125 } else {
1126 fa_to_coin_wrapper::fa_to_coin<Y>(account, coin_y_val)
1127 };
1128
1129 let (coin_x_remainder, coin_y_remainder, lp_coins) =
1130 router_ls_v05::add_liquidity<X, Y, Curve>(
1131 coin_x,
1132 coin_x_val_min,
1133 coin_y,
1134 coin_y_val_min,
1135 );
1136
1137 let account_addr = signer::address_of(account);
1138
1139 if (!is_wrapped_x) {
1140 coin::deposit(account_addr, coin_x_remainder);
1141 } else {
1142 fa_to_coin_wrapper::coin_to_fa(coin_x_remainder, account);
1143 };
1144
1145 if (!is_wrapped_y) {
1146 coin::deposit(account_addr, coin_y_remainder);
1147 } else {
1148 fa_to_coin_wrapper::coin_to_fa(coin_y_remainder, account);
1149 };
1150 aptos_account::deposit_coins(account_addr, lp_coins);
1151 }
1152
1153 /// Adds liquidity to the V1 pool using the specified distribution.
1154 /// * `account` - liquidity adding account.
1155 /// * `amount_x` - amount of coins `X` for distribution to liquidity.
1156 /// * `amount_y` - amount of coins `Y` for distribution to liquidity.
1157 /// * `bin_ids` - vector of bin IDs to which liquidity will be distributed.
1158 /// * `active_bin_id_desired` - `active_bin_id` required to be in pool
1159 /// at the time of liquidity adding.
1160 /// * `active_bin_id_slippage` - max allowed id difference between
1161 /// pool `active_bin_id` and `active_bin_id_desired`.
1162 /// * `liq_x_coins` - vector of amounts of coin `X` to add into bin with
1163 /// ID from corresponding `bin_ids` element.
1164 /// * `liq_y_coins` - vector of amounts of coin `Y` to add into bin with
1165 /// ID from corresponding `bin_ids` element.
1166 /// * `amount_x_min` - amount of X liquidity to be added at minimum.
1167 /// * `amount_y_min` - amount of Y liquidity to be added at minimum.
1168 ///
1169 /// Note: `bin_ids`, `liq_x_coins` and `liq_y_coins`
1170 /// must have the same length and contain valid values, otherwise transaction could fail.
1171 /// Note: `X` and `Y` generic coin parameters must be sorted.
1172 /// Note: `X` and `Y` coins can be added only into the active bin. Only `Y` coins can be added to bin
1173 /// with ID less then active. Only `X` coins can be added to bin with ID greater than active.
1174 public entry fun add_liquidity_v1<X, Y, BinStep>(
1175 account: &signer,
1176 amount_x: u64,
1177 amount_y: u64,
1178 bin_ids: vector<u32>,
1179 active_bin_id_desired: u32,
1180 active_bin_id_slippage: u32,
1181 liq_x_coins: vector<u64>,
1182 liq_y_coins: vector<u64>,
1183 amount_x_min: u64,
1184 amount_y_min: u64,
1185 ) {
1186 let is_wrapped_x = fa_to_coin_wrapper::is_fa_wrapped_coin<X>();
1187 let is_wrapped_y = fa_to_coin_wrapper::is_fa_wrapped_coin<Y>();
1188
1189 let coins_x = if (!is_wrapped_x) {
1190 coin::withdraw<X>(account, amount_x)
1191 } else {
1192 fa_to_coin_wrapper::fa_to_coin<X>(account, amount_x)
1193 };
1194
1195 let coins_y = if (!is_wrapped_y) {
1196 coin::withdraw<Y>(account, amount_y)
1197 } else {
1198 fa_to_coin_wrapper::fa_to_coin<Y>(account, amount_y)
1199 };
1200
1201 let (liq_tokens, leftovers_x, leftovers_y) = router_ls_v1::add_liquidity<X, Y, BinStep>(
1202 coins_x,
1203 coins_y,
1204 bin_ids,
1205 active_bin_id_desired,
1206 active_bin_id_slippage,
1207 liq_x_coins,
1208 liq_y_coins,
1209 amount_x_min,
1210 amount_y_min
1211 );
1212
1213 // Transfer liquidity NFTs to user.
1214 while (!vector::is_empty(&liq_tokens)) {
1215 let liq_token = vector::pop_back(&mut liq_tokens);
1216 token::deposit_token(account, liq_token);
1217 };
1218 vector::destroy_empty(liq_tokens);
1219
1220 // Transfer X\Y coins leftovers to user.
1221 let account_addr = signer::address_of(account);
1222
1223 if (!is_wrapped_x) {
1224 coin::deposit(account_addr, leftovers_x);
1225 } else {
1226 fa_to_coin_wrapper::coin_to_fa(leftovers_x, account);
1227 };
1228
1229 if (!is_wrapped_y) {
1230 coin::deposit(account_addr, leftovers_y);
1231 } else {
1232 fa_to_coin_wrapper::coin_to_fa(leftovers_y, account);
1233 };
1234 }
1235
1236 //
1237 // Remove liquidity
1238 //
1239
1240 /// Remove (burn) V0 liquidity coins `LP` from account, get `X` and`Y` coins back.
1241 /// * `lp_val` - amount of `LP` coins to burn.
1242 /// * `min_x_out_val` - minimum amount of X coins to get.
1243 /// * `min_y_out_val` - minimum amount of Y coins to get.
1244 ///
1245 /// Note: X, Y generic coin parameters must be sorted.
1246 public entry fun remove_liquidity_v0<X, Y, Curve>(
1247 account: &signer,
1248 lp_val: u64,
1249 min_x_out_val: u64,
1250 min_y_out_val: u64,
1251 ) {
1252 let lp_coins = coin::withdraw<LPv0<X, Y, Curve>>(account, lp_val);
1253
1254 let (coin_x, coin_y) = router_ls_v0::remove_liquidity<X, Y, Curve>(
1255 lp_coins,
1256 min_x_out_val,
1257 min_y_out_val,
1258 );
1259
1260 let account_addr = signer::address_of(account);
1261
1262 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
1263 aptos_account::deposit_coins(account_addr, coin_x);
1264 } else {
1265 fa_to_coin_wrapper::coin_to_fa(coin_x, account);
1266 };
1267
1268 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
1269 aptos_account::deposit_coins(account_addr, coin_y);
1270 } else {
1271 fa_to_coin_wrapper::coin_to_fa(coin_y, account);
1272 };
1273 }
1274
1275 /// Remove (burn) V0.5 liquidity coins `LP` from account, get `X` and`Y` coins back.
1276 /// * `lp_val` - amount of `LP` coins to burn.
1277 /// * `min_x_out_val` - minimum amount of X coins to get.
1278 /// * `min_y_out_val` - minimum amount of Y coins to get.
1279 ///
1280 /// Note: X, Y generic coin parameters must be sorted.
1281 public entry fun remove_liquidity_v05<X, Y, Curve>(
1282 account: &signer,
1283 lp_val: u64,
1284 min_x_out_val: u64,
1285 min_y_out_val: u64,
1286 ) {
1287 let lp_coins = coin::withdraw<LPv05<X, Y, Curve>>(account, lp_val);
1288
1289 let (coin_x, coin_y) = router_ls_v05::remove_liquidity<X, Y, Curve>(
1290 lp_coins,
1291 min_x_out_val,
1292 min_y_out_val,
1293 );
1294
1295 let account_addr = signer::address_of(account);
1296
1297 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
1298 aptos_account::deposit_coins(account_addr, coin_x);
1299 } else {
1300 fa_to_coin_wrapper::coin_to_fa(coin_x, account);
1301 };
1302
1303 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
1304 aptos_account::deposit_coins(account_addr, coin_y);
1305 } else {
1306 fa_to_coin_wrapper::coin_to_fa(coin_y, account);
1307 };
1308 }
1309
1310 /// Remove specified amounts of liquidity from the V1 pool.
1311 /// * `account` - liquidity removing account.
1312 /// * `bin_ids` - vector of bin IDs from which liquidity will be released.
1313 /// * `liq_amounts` - vector of amounts of liquidity to release from bin with
1314 /// ID from corresponding `bin_ids` element.
1315 /// * `amount_x_min` - minimum expected total coin `X` amount to receive after liquidity
1316 /// release from `bin_ids`.
1317 /// * `amount_y_min` - minimum expected total coin `Y` amount to receive after liquidity
1318 /// release from `bin_ids`.
1319 ///
1320 /// Note: `bin_ids` and `liq_amounts` must have the same length
1321 /// and contain valid values, otherwise not all liquidity will be released
1322 /// or transaction could fail.
1323 /// Note: if `amount_x_min` or `amount_y_min` has wrong value, user could receive less
1324 /// `X` or/and `Y` coins than expected minimum.
1325 /// Note: `X` and `Y` generic coin parameters must be sorted.
1326 public entry fun remove_liquidity_v1<X, Y, BinStep>(
1327 account: &signer,
1328 bin_ids: vector<u32>,
1329 liq_amounts: vector<u64>,
1330 amount_x_min: u64,
1331 amount_y_min: u64,
1332 ) {
1333 let liq_nfts = vector::empty<Token>();
1334
1335 let len = vector::length(&bin_ids);
1336 let i = 0;
1337 // Extract NFTs from user balance.
1338 while (i < len) {
1339 let bin_id = *vector::borrow(&bin_ids, i);
1340 let amount = *vector::borrow(&liq_amounts, i);
1341
1342 let (_, _, td_id) = liquidity_pool_v1::get_bin_fields<X, Y, BinStep>(bin_id);
1343 let token_data_id = option::destroy_some(td_id);
1344 let token_id = token::create_token_id(token_data_id, 0);
1345 let token = token::withdraw_token(account, token_id, amount);
1346
1347 vector::push_back(&mut liq_nfts, token);
1348
1349 i = i + 1;
1350 };
1351
1352 let (coins_x, coins_y) =
1353 router_ls_v1::remove_liquidity<X, Y, BinStep>(liq_nfts, amount_x_min, amount_y_min);
1354
1355 let account_addr = signer::address_of(account);
1356
1357 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<X>()) {
1358 aptos_account::deposit_coins(account_addr, coins_x);
1359 } else {
1360 fa_to_coin_wrapper::coin_to_fa(coins_x, account);
1361 };
1362
1363 if (!fa_to_coin_wrapper::is_fa_wrapped_coin<Y>()) {
1364 aptos_account::deposit_coins(account_addr, coins_y);
1365 } else {
1366 fa_to_coin_wrapper::coin_to_fa(coins_y, account);
1367 };
1368 }
1369}
1370
ABI
{
address:
"0x9dd974aea0f927ead664b9e1c295e4215bd441a9fb4e53e5ea0bf22f356c8a2b"
name:
"router"
friends:[]
exposed_functions:[
0:{
name:
"add_liquidity_v0"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"u64"
3
:
"u64"
4
:
"u64"
return:[]
1:{
name:
"add_liquidity_v05"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"u64"
3
:
"u64"
4
:
"u64"
return:[]
2:{
name:
"add_liquidity_v1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"u64"
3
:
"vector<u32>"
4
:
"u32"
5
:
"u32"
6
:
"vector<u64>"
7
:
"vector<u64>"
8
:
"u64"
9
:
"u64"
return:[]
3:{
name:
"fa_swap_coin_for_exact_coin_x1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
4:{
name:
"fa_swap_coin_for_exact_coin_x2"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
5:{
name:
"fa_swap_coin_for_exact_coin_x3"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
6:{
name:
"fa_swap_coin_for_exact_coin_x4"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
10:{
constraints:[]
11:{
constraints:[]
12:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
7:{
name:
"fa_swap_exact_coin_for_coin_x1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
8:{
name:
"fa_swap_exact_coin_for_coin_x2"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
9:{
name:
"fa_swap_exact_coin_for_coin_x3"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
10:{
name:
"fa_swap_exact_coin_for_coin_x4"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
10:{
constraints:[]
11:{
constraints:[]
12:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
11:{
name:
"remove_liquidity_v0"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"u64"
3
:
"u64"
return:[]
12:{
name:
"remove_liquidity_v05"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"u64"
3
:
"u64"
return:[]
13:{
name:
"remove_liquidity_v1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
params:[
0
:
"&signer"
1
:
"vector<u32>"
2
:
"vector<u64>"
3
:
"u64"
4
:
"u64"
return:[]
14:{
name:
"swap_coin_for_exact_coin_x1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
15:{
name:
"swap_coin_for_exact_coin_x2"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
16:{
name:
"swap_coin_for_exact_coin_x3"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
17:{
name:
"swap_coin_for_exact_coin_x4"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
10:{
constraints:[]
11:{
constraints:[]
12:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
18:{
name:
"swap_exact_coin_for_coin_x1"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
19:{
name:
"swap_exact_coin_for_coin_x2"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
20:{
name:
"swap_exact_coin_for_coin_x3"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
21:{
name:
"swap_exact_coin_for_coin_x4"
visibility:
"public"
is_entry:
true
is_view:
false
generic_type_params:[
0:{
constraints:[]
1:{
constraints:[]
2:{
constraints:[]
3:{
constraints:[]
4:{
constraints:[]
5:{
constraints:[]
6:{
constraints:[]
7:{
constraints:[]
8:{
constraints:[]
9:{
constraints:[]
10:{
constraints:[]
11:{
constraints:[]
12:{
constraints:[]
params:[
0
:
"&signer"
1
:
"u64"
2
:
"vector<u64>"
3
:
"vector<u8>"
4
:
"vector<bool>"
return:[]
structs:[
0:{
name:
"BinStepV0V05"
is_native:
false
is_event:
false
abilities:[]
generic_type_params:[]
fields:[
0:{
name:
"dummy_field"
type:
"bool"
1:{
name:
"CurveV1"
is_native:
false
is_event:
false
abilities:[]
generic_type_params:[]
fields:[
0:{
name:
"dummy_field"
type:
"bool"