Swap and Preswap

1. Construct Your Own Swap Method.

1. 1 Swap

Function params (click to open)

config: the reference of clmm globalconfig object. you can see details at Global Config ID

pool : one mutable reference of the pool.

coin_a: mutable coin a object. this type is the same as the coin a of pool.

coin_b: mutable coin b object. this type is the same as the coin b of pool.

a2b: the swap direction, a2b equals true means sold coin a then get coin b.

by_amount_in: when it equal true means want to fix the amount of input coin. when it equal false means want to fix the amount of output coin.

amount: when by_amount_in equals true, amount means the quantity of input coin, when by_amount_in equals false, amount means the quantity of output coin.

amount_limit: the threshold value of coin. when by_amount_in equals true, it means the minimum amount about received coin, when by_amount_in equals false, it means the maximum amount about sold.

sqrt_price_limit: two constant of sqrt price(x64 fixed-point number). When a2b equals true, it equals 4295048016, when a2b equals false, it equals 79226673515401279992447579055. Just use the default values.

clock: the sui clock object.

You can implement swaps like the following examples. This is divided into two instances: one with a partner and the other without. For a detailed introduction to the Cetus partner, you can refer to cetus partner.

fun swap<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: &mut Coin<CoinTypeA>,
    coin_b: &mut Coin<CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    sqrt_price_limit: u128,
    clock: &Clock,
    ctx: &mut TxContext
) {
    // flash swap first
    let (receive_a, receive_b, flash_receipt) = pool::flash_swap<CoinTypeA, CoinTypeB>(
        config,
        pool,
        a2b,
        by_amount_in,
        amount,
        sqrt_price_limit,
        clock
    );
    let (in_amount, out_amount) = (
        pool::swap_pay_amount(&flash_receipt),
        if (a2b) balance::value(&receive_b) else balance::value(&receive_a)
    );

    // pay for flash swap
    let (pay_coin_a, pay_coin_b) = if (a2b) {
        (coin::into_balance(coin::split(&mut coin_a, in_amount, ctx)), balance::zero<CoinTypeB>())
    } else {
        (balance::zero<CoinTypeA>(), coin::into_balance(coin::split(&mut coin_b, in_amount, ctx)))
    };

    coin::join(&mut coin_b, coin::from_balance(receive_b, ctx));
    coin::join(&mut coin_a, coin::from_balance(receive_a, ctx));

    pool::repay_flash_swap<CoinTypeA, CoinTypeB>(
        config,
        pool,
        pay_coin_a,
        pay_coin_b,
        flash_receipt
    );
}

/// Swap with partner.
fun swap_with_partner<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    partner: &mut Partner,
    coin_a: &mut Coin<CoinTypeA>,
    coin_b: &mut Coin<CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    sqrt_price_limit: u128,
    clock: &Clock,
    ctx: &mut TxContext
) {
    let (receive_a, receive_b, flash_receipt) = pool::flash_swap_with_partner<CoinTypeA, CoinTypeB>(
        config,
        pool,
        partner,
        a2b,
        by_amount_in,
        amount,
        sqrt_price_limit,
        clock
    );
    let (in_amount, out_amount) = (
        pool::swap_pay_amount(&flash_receipt),
        if (a2b) balance::value(&receive_b) else balance::value(&receive_a)
    );

    // pay for flash swap
    let (pay_coin_a, pay_coin_b) = if (a2b) {
        (coin::into_balance(coin::split(&mut coin_a, in_amount, ctx)), balance::zero<CoinTypeB>())
    } else {
        (balance::zero<CoinTypeA>(), coin::into_balance(coin::split(&mut coin_b, in_amount, ctx)))
    };

    coin::join(&mut coin_b, coin::from_balance(receive_b, ctx));
    coin::join(&mut coin_a, coin::from_balance(receive_a, ctx));

    pool::repay_flash_swap_with_partner<CoinTypeA, CoinTypeB>(
        config,
        pool,
        partner,
        pay_coin_a,
        pay_coin_b,
        flash_receipt
    );
}

2. Using Existing Swap Methods

2.1 Aggregator contract (recommend)

If you just want to call the existing Cetus swap method using a Move call, we can use the swap method of the Cetus aggregator that has already been deployed on the sui mainnet.

Contract Code https://suivision.xyz/package/0x11451575c775a3e633437b827ecbc1eb51a5964b0302210b28f5b89880be21a2?tab=Code

Function params (click to open)

config: the reference of clmm globalconfig object. you can see details at Global Config ID

pool : one mutable reference of the pool.

partner: cetus partner object.

coin_a: coin a object. this type is the same as the coin b of pool. This method will use all balance of this coin, it you want to swap 1000 a to b, you need to split 1000 a before swap.

clock: the sui clock object.

Call this method by ts sdk

2.2 integrate contract

Contract Code https://suivision.xyz/package/0x3a5aa90ffa33d09100d7b6941ea1c0ffe6ab66e77062ddd26320c1b073aabb10?tab=Code

0x3a5aa90ffa33d09100d7b6941ea1c0ffe6ab66e77062ddd26320c1b073aabb10::router::swap

Function params (click to open)

config: the reference of clmm globalconfig object. you can see details at Global Config ID

pool : one mutable reference of the pool.

coins_a: coins a object vector. this type is the same as the coin a of pool.Future it will be taken as Coin<CoinTypeA> and Coin<CoinTypeB>.

coins_b: coins b object vector. this type is the same as the coin b of pool.

a2b: the swap direction, a2b equals true means sold coin a then get coin b.

by_amount_in: when it equal true means want to fix the amount of input coin. when it equal false means want to fix the amount of output coin.

amount: when by_amount_in equals true, amount means the quantity of input coin, when by_amount_in equals false, amount means the quantity of output coin.

sqrt_price_limit: two constant of sqrt price(x64 fixed-point number). When a2b equals true, it equals 4295048016, when a2b equals false, it equals 79226673515401279992447579055. Just use the default values.

use_coin_value:This parameter determines whether to directly use the input coin value as the amount in. If so (i.e. true), it will ignore the passed-in amount and use the coin value as the amount instead; otherwise, it will use the input amount (i.e. amount of the 'input' coin). This parameter is only effective with fixed input (by_amount_in = true). Of course, this method is designed for our legacy router service, which is why this additional parameter is included.

clock: the sui clock object.


3. Pre swap clmmpool/sources/pool

Users can use this method to pre-calculate the corresponding amount out for a swap on-chain.

Last updated