Swap mode

In this section, we simply discuss 4 swap mode in core contracts.

Background

iZiSwap consists of core contracts (iZiSwapPool, iZiSwapFactory) and periphery contracts (LiquidityManager, LimitOrderManager, Swap, Quoter). In our sdk or frontend-app, we usually call interfaces of periphery contracts, and the periphery contracts will call corresponding core-contracts interfaces according to our params.

The most frequently used function calls are swapAmount() and swapDesire() in the Swap contract from periphery contracts set. Here desire means whether the the amount of the output token is pre-determined. For example, if you want to swap M tokenA - > N tokenB, when M is pre-determined, swapAmount() should be invoked. If N is pre-determined, use swapDesire().

When we call the swapAmount() interface in Swap, the Swap contract will first split swap path acquired from parameter into several token pairs (etc, list of tuples like (payedToken, acquiredToken, fee)). The path[0].payedToken is user’s payed token. And path[path.length-1].acquiredToken is then token which user finally would buy.

On the contrary, when calling swapDesire(), user’s payed token is not path[0].payedToken, and is path[path.length-1].payedToken instead. (We will clarify the construction of path in the following sections.)

When Swap contract gets the path (list of tokenPair) parameter, it will traversal each token pair in order and call corresponding swap interface of corresponding pool contract each to swap.

iZiSwapPool contract provides 4 types of swap interfaces for 4 modes.

Swap mode in core contracts

In the core contract, we implement 4 swap interface for 4 different modes, which consists of swapX2Y, swapX2YDesireY, swapY2X and swapY2XDesireX.

each token pair has an iZiSwapPool contract if this pair has been established through iZiSwapFactory before, all options which involves liquidity, limit order and swap of this pair will be delivered from periphery to this pool.

Suppose the token pair is (tokenA, tokenB, fee), and we ignore fee here.

If the address of tokenA is smaller than tokenB, then in this pool, we call tokenA as tokenX and call tokenB as tokenY, otherwise, we call tokenA as tokenY and tokenB as tokenX.

swapX2Y

when we call pool’s swapX2Y(…) interface, it means that we want to pay some tokenX to get tokenY and the limit undecimal amount of tokenX is specified as a parameter in this interface.

swapX2YDesireY

when we call pool’s swapX2YDesireY(…) interface, it means that we want to pay some tokenX to get tokenY and the at least undecimal amount of tokenY is specified as a parameter in this interface. In this interface, the amount is desired amount of tokenY and that’s why we named this interface as swapX2YDesireY.

swapY2X

when we call pool’s swapY2X(…) interface, it means that we want to pay some tokenY to get tokenX and the limit undecimal amount of payed tokenY is specified as a parameter in this interface.

swapY2XDesireX

when we call pool’s swapY2XDesireX(…) interface, it means that we want to pay some tokenY to get tokenX and the at least undecimal amount of tokenX is specified as a parameter in this interface. In this interface, the at least amount is desired amount of tokenX and that’s why we named this interface as swapY2XDesireX.

For instance, we are calling Swap.swapAmount(…) for paying certain amount of tokenA to get tokenB.

And we assume that the path contains no hop tokens, i.e. swap tokenA -> tokenB directly. Then, the logic of swapAmount() can be simply viewed as following pseudo code.

 1// we want to pay amountA (undecimal amount) of tokenA to get
 2// some tokenB
 3const pool = getiZiSwapPoolByPair(tokenA.address, tokenB.address, fee)
 4if (tokenA.address.toLowerCase() < tokenB.address.toLowerCase()) {
 5    // in the pool, tokenA is tokenX
 6    // tokenB is tokenY
 7    // because each pool only serves one pair, so we donot need to specify
 8    // tokenA or tokenB or fee when calling swap interface of pool
 9    pool.swapX2Y(amountA)
10} else {
11    // in the pool, tokenA is tokenB
12    // tokenB is tokenX
13    // because each pool only serves one pair, so we donot need to specify
14    // tokenA or tokenB or fee when calling swap interface of pool
15    pool.swapY2X(amountA)
16}