Architecture

This document explains the logic behind STON.fi Jetton-to-Jetton DEX

Actors

Router

The router is the contract that acts as an entrypoint for all DEX calls. It is responsible for routing all Jetton calls with transfer_notification op to the correct pool contract.

It acts as a sovereign over the DEX, and can be used to lock/unlock trading on all pools, to change fees on a certain pool or to upgrade its own contract. The router is the only contract that can be upgraded. Each Jetton that goes through the DEX is owned by the router. The router does not store anything about pairs.

Pool

The pool is the contract that stores the AMM data for a certain pair and is responsible for handling "swaps" or providing liquidity for a certain pool. For each pair (e.g. TOKEN/USDT), there is only a single pool contract. The pool is also a Jetton Minter, and handles minting/burning of Liquidity Provider Jettons. All the swap/lp calculations are done in the pool contract.

Account

The account contract holds information about the liquidity provided by the user before minting new liquidity. It interacts only with a single pool contract. For each user, there is single account contract for each pool. The router "routes" the temporary liquidity to the correct account contract. Then the account contract calls the pool contract again to mint new liquidity (once it satisfies some requirements).

Wallet (for LP jettons)

The wallet contract is a standard Jetton wallet and is used to hold the LP Jetton minted by Pools.

Calls descriptions

Swap

Lets assume that Alice wants to buy TOKEN using USDT. She should initialize a simple transfer to her own USDT Wallet with a custom payload. Once the Router receives the confirmation of the transfer, it will call the Pool contract to perform the real swap. Then the Pool contract will return the TOKEN Jetton calling pay_to op to the Router.

Providing liquidity (both amounts)

Now Alice wants to provide liquidity to the TOKEN/USDT pair. This process must be done via two different calls. Obviously, since wallets support up to 4 transactions at same time, it is possible to call both calls at the same time (at least, from the user's perspective).

At the beginning, she should start a transfer to her own USDT Wallet with a custom payload. Once the Router receives the confirmation of the transfer, it will call the Pool contract, and then the Pool contract will route the request to her own Account contract. Once the request arrives to the Account contract, the first phase ends here. This time the Account contract doesn't generate any transactions.

In Dex v1 it is possible to provide liquidity using a different ratio than the current one in the pool, thus the unbalanced part will be lost to the user and distributed across all liquidity providers. In Dex v2 always a max amount of liquidity is minted to the user, meaning the unbalanced amount of a tokens is automatically swapped using the current token ratio in the pool.

Now, Alice makes another transfer of the other Jetton (in our case, TOKEN) in the same way as before. This time, the Account contract will generate a new message to the Pool contract to mint new liquidity.

Providing liquidity (single side provision)

Dex v2 supports liquidity provision using only one token by automatically performing a swap before minting liquidity

Creating a pool

V1

To create a new Pool, just provide the minimum amount of liquidity to pair (1001 Jettons). This initial liquidity will be sent to null address. Any LP calls after this will mint LP Jettons to a user.

V2

To create a new Pool, just provide the minimum amount of liquidity to pair (1001 Jettons). A basic amount of 1001 lp tokens will be reserved on pool on initial liquidity deposit with the rest going to the user.

Stableswap

Creation of a stableswap pool is handled directly by STON.fi and cannot be done by users.

Last updated