Account Name or Address / Txn Hash or Version / Block Height or Version

Account

0.197779 APT

Balance

MultiRouter

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"
}
]
}
]
}

© 2025 Aptos Labs