SunSwap Overview

SunSwap protocol keywords: Automated market maker (AMM), liquidity pool and swap

Background

SunSwap AMM (automated market maker) adopts the most used trading model in the world of DeFi today. Unlike the order book, AMMs utilize the constant product model to calculate tokens in the pool, where trades are automatically executed, and the liquidity supply of the trading pair is ensured.

Anyone can deposit a token into a pool in exchange for the pool's dedicated token (LP token) of an equivalent value, and thus become a liquidity provider (LP) for the pool. The amount of the LP token received divided by the pool's total LP reserves represents the liquidity provider's share of assets in the pool, and the liquidity provider can redeem the above assets at any time.

Mechanism

Swapping is based on the constant product formula, with x and y representing the amount of two different tokens (assumed to be token X and token Y), then:

xy=kx * y = k

If we want to swap X for Y from the liquidity pool, and assume that the amount of X entered is Δx and the amount of Y obtained is Δy, provided that the pool has sufficient funds, then:

(x+Δx)×(yΔy)=kΔy=ykx+Δx=Δx×yx+Δx(x + \Delta x) \times (y - \Delta y) = k \\\\ \Delta y = y - \frac{k}{x + \Delta x} = \frac{\Delta x \times y}{x + \Delta x}

This means that the product of the two tokens in the liquidity pool remains unchanged after the transaction. In this case, if the volume of a transaction only accounts for a minimal fraction of the liquidity pool's total volume, then the transaction price will approximate the ratio of the two tokens' amount:

pricey=ΔxΔy=x+Δxyxyprice_y = \frac{\Delta x}{\Delta y} = \frac{x + \Delta x}{y} \approx \frac{x}{y}

However, the price of y in the liquidity pool is xy\frac{x}{y} before the swap. This results in a slippage of y's price:

Slippagey=ΔxΔyxy=ΔxySlippage_y = \frac{\Delta x}{\Delta y} - \frac{x}{y} = \frac{\Delta x}{y}

The larger the transaction volume Δx, the greater the slippage and the more the transaction price deviates from the actual price; likewise, more funds and greater depth in the pool can reduce the slippage and thus lower the losses for users. In actual SunSwap transactions, a 0.3% fee will be deducted before the calculation.

Example: Suppose the liquidity pool has 100 X and 1 Y. If a user wants to trade 20 X, then the actual amount of X traded will be 19.94 X (net of a 0.3% fee), according to the formula xy = k:

(100+19.94)×(1Δy)=100Δy=0.1662(100 + 19.94) \times (1 - \Delta y) = 100 \\\\ \Delta y = 0.1662

Liquidity Pool

The SunSwap contract of Sun.io allows users to swap between regular tokens and add and remove liquidity. Its V1 and V2 contracts are now running on the TRON MainNet.

V1

Factory contract address: TXk8rQSAvPvBBNtqSoY6nCfsXWCSSpTVQF

V2

Factory contract address: TKWJdrQkqHisa1X8HUdHEfREvTzw4pMAaY

Router contract address: TXF1xDbVGdxFGbovmmmXvBGu8ZiE3Lq4mR

Note: The old Router contract address TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax has been deprecated.

Interact with Contract

We utilize TronWeb to facilitate interaction with on-chain contracts. First, you need to initialize the TronWeb instance.

Initialize the TronWeb
const TronWeb = require('tronweb')
const privateKey = process.env.PRIVATE_KEY
const apiKey = process.env.API_KEY

var tronWeb = new TronWeb({
	fullHost: "https://api.trongrid.io",
	headers: { "TRON-PRO-API-KEY": apiKey },
	privateKey: privateKey,
      })

Get Liquidity Pool's Information

  • Get a liquidity pool's address in V1

    • Function: getExchange(address)

    • Parameter: Token address

>>> let contract = await tronWeb.getContract('TXk8rQSAvPvBBNtqSoY6nCfsXWCSSpTVQF')
>>> await contract.methods.getExchange('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t').call() 
0x4cAD2750821493b093133B7bf10568bAEc000971
  • Get a liquidity pool's address in V2

    • Function: getPair(address, address)

    • Parameter: token0's address, token1's address

>>> let contract = await tronWeb.getContract('TKWJdrQkqHisa1X8HUdHEfREvTzw4pMAaY')
>>> await contract.methods.getPair('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', 'TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR') 
0x4cAD2750821493b093133B7bf10568bAEc000971

Execute Transactions

  • Sell TRX to buy Token in V1

    • Function: trxToTokenTransferInput(uint256, uint256, address)

    • Parameters: minimum Token amount expected to buy, time window, recipient's address

let contract = await tronWeb.getContract('TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
>>> await contract.methods.trxToTokenTransferInput(100, 1662825600, 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
  • Sell Token to buy TRX in V1

    • Function: tokenToTrxTransferInput(uint256, uint256, uint256, address)

    • Parameters: Amount of Token to sell, minimum TRX amount expected to buy, time window, recipient's address

>>> let contract = await tronWeb.getContract('TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
>>> await contract.methods.tokenToTrxTransferInput(100, 1500, 1662825600, 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE') 
  • Sell Token to buy Token in V1

    • Function: tokenToTokenSwapInput( uint256, uint256, uint256, uint256, address)

    • Parameters: Amount of Token to sell, minimum Token amount expected to buy, minimum Token amount expected to buy, time window, recipient's address

>>> let contract = await tronWeb.getContract('TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
>>> await contract.methods.tokenToTokenSwapInput(100, 100, 1500,1662825600,'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE') 
  • Sell Token to buy Token in V2

    • Function: swapExactTokensForTokens( uint, uint, address[], address, uint)

    • Parameters: Amount of Token to sell, minimum Token amount expected to buy, swap route, recipient's address, time window

>>> let contract = await tronWeb.getContract('TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax')
>>> await contract.methods.swapExactTokensForTokens(1000000000000000000,1000000,['TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf','TF17BgPaZYbz8oxbjhriubPDsA7ArKoLX3'],'TF5MekHgFz6neU7zTpX4h2tha3mijDUj3z',1662825600)
  • Sell TRX to buy Token in V2

    • Function: swapExactETHForTokens(uint, address[], address, uint)

    • Parameters: Token amount expected to buy, swap route, recipient's address, time window

>>> let contract = await tronWeb.getContract('TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax')
>>> await contract.methods.swapExactETHForTokens(100000000,1,['TYsbWxNnyTgsZaTFaue9hqpxkU3Fkco94a','TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf'],'TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z',1662825600)
  • Sell Token to buy TRX in V2

    • Function: swapExactTokensForETH(uint, uint, address[] , address, uint)

    • Parameters: Amount of Token to sell, minimum TRX amount expected to buy, swap route, buyer's address, time window

>>> let contract = await tronWeb.getContract('TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax')
>>> await contract.methods.swapExactTokensForETH(1000000,1000000,['TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf','TYsbWxNnyTgsZaTFaue9hqpxkU3Fkco94a'],'TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z',1662825600)

Add & Remove Liquidity

  • Add liquidity in V1

    • Function: addLiquidity(uint256, uint256, uint256)

    • Parameters: Minimum liquidity amount expected to get, maximum liquidity amount to add, time window

>>> let contract = await tronWeb.getContract('TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
>>> await contract.methods.addLiquidity(100, 100, 1662825600) 
  • Remove liquidity in V1

    • Function: removeLiquidity(uint256, uint256,uint256, uint256)

    • Parameters: Liquidity amount to remove, minimum TRX amount expected to get, minimum token amount expected to get, time window

>>> let contract = await tronWeb.getContract('TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE')
>>> await contract.methods.removeLiquidity(100, 100, 100, 1662825600) 
  • Add liquidity in V2

    • Function: addLiquidity(address,address,uint,uint,uint,uint,address,uint)

    • Parameters: tokenA's address, tokenB's address, tokenA's amount expected to add, tokenB's amount expected to add, minimum receiving amount of the tokenA added, minimum receiving amount of the tokenB added, target liquidity pool's address, time window

>>> let contract = await tronWeb.getContract('TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax')
>>> await contract.methods.addLiquidity('TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf','TF17BgPaZYbz8oxbjhriubPDsA7ArKoLX3',100000000,27661108481018349141,5000000,200000000000000000000,TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z,1662825600)
  • Remove liquidity in V2

    • Name: removeLiquidity(address,address,uint,uint,uint,address,uint)

    • Parameters: tokenA's address, tokenB's address, amount of liquidity to remove, minimum tokenA amount expected to get, minimum tokenB amount expected to get, token's receiving address, time window

>>> let contract = await tronWeb.getContract('TKzxdSv2FZKQrEqkKVgp5DcwEXBEKMg2Ax')
>>> await contract.methods.removeLiquidity('TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf','TF17BgPaZYbz8oxbjhriubPDsA7ArKoLX3',100000000,1,1,TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z,1962825600)

Last updated