This document explains the logic behind Jetton-to-Jetton DEX



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.


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. WTON/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.


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


Lets assume that Alice wants to buy WTON 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 WTON Jetton calling pay_to op to the Router.

Providing liquidity

Now Alice wants to provide liquidity to the WTON/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.
Now, Alice makes another transfer of the other Jetton (in our case, WTON) in the same way as before. This time, the Account contract will generate a new message to the Pool contract to mint new liquidity.

Creating a pool

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.