SUN.io Docs
SUN.ioSunPump
  • SUN.io Overview
    • Get Started(TRON)
      • Create a Wallet
      • TRON Network Token Standards
      • Connect Your Wallet to SUN.io
    • Risks
    • Whitepaper
    • Terms of Service
    • Privacy Policy
    • Announcement
  • GET START
    • Exchange
      • Token Swaps
        • How to authorize a token?
        • How to exchange tokens?
        • How to check my recent transaction history?
        • How to view 24h price trend of a pair ?
      • Stablecoin Pool
        • Stablecoin pool overview
        • How to swap stablecoins?
        • How to provide liquidity for a stablecoin pool?
        • How to withdraw liquidity from a stablecoin pool?
        • How to check the liquidity you have provided?
      • Smart Router
      • Trading Fee
        • Claim Fee Rewards
      • Liquidity Pool
        • How to create a trading pair?
        • How to add liquidity?
        • How to remove liquidity?
        • How to calculate the ratio of tokens to be added to/removed from the pool?
        • How to record a new token?
        • What's the initial price for creating a fund pool?
      • Token Lists
    • Mining Pool
      • Mining Rules of SUN.io
      • How to participate in liquidity mining?
      • How to earn liquidity mining rewards?
      • How to exit liquidity mining?
      • How to calculate the boost rate of LP mining pool?
      • How to lock SUN?
      • How to vote?
      • How to reset votes?
      • Intelligent Boost Mining Pool
        • How to participate in Fixed Staking?
        • How to stake more assets in Fixed Staking?
        • How to extend duration in Fixed Staking?
        • How to make an early withdrawal in Fixed Staking?
        • How to claim rewards in Fixed Staking?
      • Farm
      • Ended Farming Pools
    • SunPump
      • 🌞 How to Participate?
      • 🚀 How to Launch?
      • 💡 Token Details
      • 👤 Personal Profile
      • 🏦 Service Fees
      • How to Use DLive Streaming on SunPump
    • SunPump Referral
      • How to Join
      • Rules
      • FAQ
    • PSM
      • How to swap between USDD and other stablecoins at 1:1 ratio in PSM?
    • Tokenomics
      • SUN Tokenomics
        • Buyback & Burning of the SUN Token
      • veSUN
      • Airdrop
  • GOVERNANCE
    • SUN DAO Governance
    • Participating Governance
      • Proposal
        • SUN DAO Forum
        • How to get more votes?
        • Create Proposal
        • How to vote on the SUN DAO?
        • SUN DAO proposal
      • Governance Rights
        • Weight
        • veSUN
  • DEVELOPERS
    • Swap
      • StableSwap Overview
      • SunSwap Overview
      • SunSwap V3 Overview
      • Smart Router
        • Contract
        • Calculation Service
        • Exchange Functions
        • Detailed Development Steps
    • Mining
      • Smart Mining V1
      • Smart Mining V2
      • Governance Mining
    • Sunpump
      • Sunpump Contracts
    • Github
    • Contracts and ABIs
  • FAQ
    • How to use Sun.io in TronLink Mobile?
    • How is price determined?
    • What tokens are supported for swap?
    • Why does my exchange fail?
    • Detailed Explanation of SUN.io Platform Energy Subsidies
Powered by GitBook
On this page
  • Background
  • Mechanism
  • Liquidity Pool
  • Interact with Contract
  • Get Liquidity Pool's Information
  • Execute Transaction
  • Add & Remove Liquidity
  1. DEVELOPERS
  2. Swap

StableSwap Overview

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

PreviousSwapNextSunSwap Overview

Last updated 1 month ago

Background

As stablecoins evolve, the popular TRC20-USDT is no longer alone on TRON. TRON's expanding stablecoin family has welcomed USDJ, TUSD, USDC, USDD, and other new members. The growing market share and variety of stablecoins have given rise to more complex demand for swapping between different stablecoins. Sun.io's StableSwap protocol is designed to provide swap services for stablecoins or tokens of equivalent value, and it offers lower fees and slippage than competitors in the market in the following ways:

  • Slippage of StableSwap can be reduced to zero when there are sufficient tokens in the liquidity pool;

  • StableSwap will increase the transaction price of a token to avoid depletion of its supply in the liquidity pool.

Mechanism

To maintain the transaction price at 1, the most straightforward way is to use the equation of a straight line with a slope of -1 (i.e. x + y = k). The price should also be able to adjust itself to avoid liquidity depletion, which requires the constant product formula x * y = k. The StableSwap protocol incorporates both constant sum and constant product. Its model can be simply regarded as the weighted sum of a constant sum and a constant product, as described by the market making formula in the .

Ann∑i=0nxi+D=ADnn+Dn+1nn∏i=1nxiA n^n \sum_{i=0}^{n} x_i + D = A D n^n + \frac { D^{n + 1} } { n^n \prod_{i=1}^{n} x_i }Anni=0∑n​xi​+D=ADnn+nn∏i=1n​xi​Dn+1​

According to the above formula, token swaps have an impact on the value of xix_ixi​. Take 2pool (USDD, USDT) as an example: suppose the amount before the transaction is (x1,x2)(x_1, x_2)(x1​,x2​). When a user swaps x1′−x1x_{1}^{'} - x_1x1′​−x1​ USDD for USDT, the value of x1x_1x1​ will change to x1′x_{1}^{'}x1′​. Substitute x1′x_{1}^{'}x1′​ into the above equation and you will get the new x2′x_{2}^{'}x2′​, and x2−x2′x_2 - x_{2}^{'}x2​−x2′​ represents the amount of USDT the user will obtain. The values of both AAA and DDD remain unchanged during the calculation. AAA is a constant, and the value of DDD can be found with a given xix_ixi​ using Newton's Method.

D1=D0−f(D0)f′(D0)=D0−D0n+1nn∏i=1nxi+D0(Ann−1)−Ann∑i=1nxi(n+1)D0nnn∏i=1nxi+Ann−1=nD0n+1nn∏i=1nxi+Ann∑i=1nxi(n+1)D0nnn∏i=1nxi+Ann−1\begin{align*} D_1 &= D_0 - \frac{f(D_0)}{f'(D_0)} \\ &= D_0 - \frac{\frac{D_0^{n + 1}}{n^n \prod_{i=1}^{n} x_i} + D_0 (A n^n - 1) - A n^n \sum_{i=1}^{n} x_i } {\frac{(n + 1) D_0^n}{n^n \prod_{i=1}^{n} x_i} + A n^n - 1} \\ &= \frac{ \frac{n D_0^{n + 1}}{n^n \prod_{i=1}^{n} x_i} + A n^n \sum_{i=1}^{n} x_i} {\frac{(n + 1) D_0^n}{n^n \prod_{i=1}^{n} x_i} + A n^n - 1} \end{align*}D1​​=D0​−f′(D0​)f(D0​)​=D0​−nn∏i=1n​xi​(n+1)D0n​​+Ann−1nn∏i=1n​xi​D0n+1​​+D0​(Ann−1)−Ann∑i=1n​xi​​=nn∏i=1n​xi​(n+1)D0n​​+Ann−1nn∏i=1n​xi​nD0n+1​​+Ann∑i=1n​xi​​​

Let S=∑i=1nxi,Dp=D0D0nnn∏i=1nxi S = \sum_{i=1}^{n} x_i , D_p = \frac{D_0 D_0^n}{ n^n \prod_{i=1}^{n} x_i} S=∑i=1n​xi​,Dp​=nn∏i=1n​xi​D0​D0n​​, Substitute these expressions into the above equation and you can get:

D1=(nDp+AnnS)D0(n+1)Dp+(Ann−1)D0D_1 =\frac{(n D_p + A n^n S) D_0}{ (n + 1) D_p + (A n^n - 1) D_0}D1​=(n+1)Dp​+(Ann−1)D0​(nDp​+AnnS)D0​​

The corresponding contract code is shown below:

Newton's Method
def get_D(xp: uint256[N_COINS], amp: uint256) -> uint256:
    S: uint256 = 0
    for _x in xp:
        S += _x
    if S == 0:
        return 0

    Dprev: uint256 = 0
    D: uint256 = S
    Ann: uint256 = amp * N_COINS
    for _i in range(255):
        D_P: uint256 = D
        for _x in xp:
            D_P = D_P * D / (_x * N_COINS) 
        Dprev = D
        D = (Ann * S + D_P * N_COINS) * D / ((Ann - 1) * D + (N_COINS + 1) * D_P)
        if D > Dprev:
            if D - Dprev <= 1:
                break
        else:
            if Dprev - D <= 1:
                break
    return D

Liquidity Pool

The StableSwap contract of Sun.io allows users to swap between stablecoins and add or remove liquidity. Its USDD-USDT liquidity pool, USDJ-TUSD-USDT liquidity pool, and USDC liquidity pool are now available on the TRON MainNet.

USDD-USDT pool

MainNet contract address: TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c

USDJ-TUSD-USDT pool

MainNet contract address: TKcEU8ekq2ZoFzLSGFYCUY6aocJBX9X31b

USDC pool

MainNet contract address: TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c

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's token address

    • Function: coins(uint256)

    • Parameter: The i-th token of the stablecoin pool

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.coins(0).call() 
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t 
  • Get a liquidity pool's size

    • Function: balances(uint256)

    • Parameter: The i-th token of the stablecoin pool

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.balances(0).call()
1000000000000
  • Get a liquidity pool's LP token address

    • Function: lp_token()

    • Parameter: No input parameters

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.lp_token().call() 
TD3et9gS2pYz46ZC2mkCfYcKQGNwrnBLef 
  • Get A's value

    • Function: A()

    • Parameter: No input parameters

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.A().call()
300

Execute Transaction

  • Get the amount of Token to swap for

    • Function: get_dy(uint128,uint128,uint256)

    • Parameters: In-pool sequence number of the token to be sold, in-pool sequence number of the token to be bought, amount of the token to be sold

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.get_dy(0, 1, 100).send() 
103
  • Swap

    • Function: exchange(uint128,uint128,uint256,uint256)

    • Parameters: In-pool sequence number of the token to be sold, in-pool sequence number of the token to be bought, amount of the token to be sold, minimum amount expected to get

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.exchange(0, 1, 100, 99).send() 

Add & Remove Liquidity

  • Add liquidity

    • Function: add_liquidity(uint256[n],uint256)

    • Parameters: Amount of all tokens to add, minimum LP token amount expected to get

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.add_liquidity(100, 100, 299).send() 
  • Remove liquidity

    • Function: remove_liquidity(uint256, uint256[n])

    • Parameters: LP token amount to remove, minimum token amount expected to get

>>> let contract = await tronWeb.getContract('TNTfaTpkdd4AQDeqr8SGG7tgdkdjdhbP5c')
>>> await contract.methods.remove_liquidity(299.9, 100, 100).send() 
SUN WhitePaper