DexPair
This smart contract defines the logic for managing exchange, cross pair exchange and deposit/withdraw liquidity inside the pair’s pool.
Smart contract of the dex pair responsible for managing exchange, cross pair exchange, deposit/withdraw liquidity inside the pair’s pool.
Derives following classes and interfaces: DexContractBase, IDexPair, IAcceptTokensTransferCallback, IUpgradableByRequest, IResetGas, ITokenOperationStructure.

Getters

getRoot

function getRoot() override external view responsible returns (address dex_root)
Returns address of the current Dex root.
Return values:
Name
Type
Description
dex_root
address
Address of the pair’s root address

getTokenRoots

function getTokenRoots() override external view responsible returns (address left, address right, address lp)
Returns left, right root and liquidity pool root address.
Return values:
Name
Type
Description
left
address
Address of the pair’s left token root
right
address
Address of the pair’s right token root
lp
address
Address of the liquidity pool root

getTokenWallets

function getTokenWallets() override external view responsible returns (address left, address right, address lp)
Returns left, right and liquidity pool wallet address.
Return values:
Name
Type
Description
left
address
Address of the wallet’s left token
right
address
Address of the wallet’s right token
lp
address
Address of the liquidity pool wallet

getVersion

function getVersion() override external view responsible returns (uint32 version)
Returns current version of the dex pair.
Return values:
Name
Type
Description
version
uint32
Current version

getVault

function getVault() override external view responsible returns (address dex_vault)
Returns the vault of the desired dex pair.
Return values:
Name
Type
Description
dex_vault
address
Vault address of dex pair

getVaultWallets

function getVaultWallets() override external view responsible returns (address left, address right)
Returns left and right vault wallet addresses.
Return values:
Name
Type
Description
left
address
Vault address of the left pair’s token
right
address
Vault address of the right pair’s token

setFeeParams

function setFeeParams(uint16 numerator, uint16 denominator) override external onlyRoot
Sets fees based on the numerator and denominator and emits FeesParamsUpdated to notify that new fees were set.
Parameters:
Name
Type
Description
numerator
uint16
Numerator value for setting fees
denominator
uint16
Denominator value for setting fees

getFeeParams

function getFeeParams() override external view responsible returns (uint16 numerator, uint16 denominator)
Returns fee numerator and denominator
Return values:
Name
Type
Description
numerator
uint16
Numerator value
denominator
uint16
Denominator value

isActive

function isActive() override external view responsible returns (bool)
Checks whether the DexPair account is active, returns true if yes, false if not.
Return values:
Type
Description
bool
DexPair account active or not

getBalances

function getBalances() override external view responsible returns (IDexPairBalances)
Returns liquidity pool supply and left and right balance.
Return values:
Type
Description
IDexPairBalances
Pair’s balance information

Direct operations

buildExchangePayload

function buildExchangePayload(uint64 id, uint128 deploy_wallet_grams, uint128 expected_amount) external pure returns (TvmCell)
Builds the payload data for the exchange operation and converts it to cell.
Parameters:
Name
Type
Description
id
uint64
Id of the operation call
deploy_wallet_grams
uint128
Fee for deploying wallet
expected_amount
uint128
Expected amount of receive token after exchange
Return values:
Type
Description
TvmCell
Payload data needed for exchange

buildDepositLiquidityPayload

function buildDepositLiquidityPayload(uint64 id, uint128 deploy_wallet_grams) external pure returns (TvmCell)
Builds the payload data for the deposit liquidity operation and converts it to cell.
Parameters:
Name
Type
Description
id
uint64
Id of the operation call
deploy_wallet_grams
uint128
Fee for deploying wallet
Return values:
Type
Description
TvmCell
Payload data needed for deposit to liquidity pool

buildWithdrawLiquidityPayload

function buildWithdrawLiquidityPayload(uint64 id, uint128 deploy_wallet_grams) external pure returns (TvmCell)
Builds the payload data for the withdraw liquidity operation and converts it to cell.
Parameters:
Name
Type
Description
id
uint64
Id of the operation call
deploy_wallet_grams
uint128
Fee for deploying wallet
Return values:
Type
Description
TvmCell
Payload data needed for withdrawal from liquidity pool

buildCrossPairExchangePayload

function buildCrossPairExchangePayload(uint64 id, uint128 deploy_wallet_grams, uint128 expected_amount, TokenOperation[] steps) external pure returns (TvmCell)
Builds the payload data for the cross-pair exchange operation and converts it to cell.
Parameters:
Name
Type
Description
id
uint64
Id of the operation call
deploy_wallet_grams
uint128
Fee for deploying wallet
expected_amount
uint128
Expected amount of receive token after exchange
steps
TokenOperation[]
Next pairs for exchange
Return values:
Type
Description
TvmCell
Payload data needed for cross-pair exchange

onAcceptTokenTransfer

function onAcceptTokensTransfer(address token_root, uint128 tokens_amount, address sender_address, address sender_wallet, address original_gas_to, TvmCell payload) override external
Changes values of contract’s data such as left balance, right balance, liquidity pool supply etc. according to the operation that is related to the token transfer such as: Deposit liquidity, Exchange, Cross pair exchange and according to the operations flows (right to left/left to right). Depending on the operation success callbacks are called and proper events are emitted. If any of the operations are canceled, tokens used in transfer are burned and cancel callbacks and events are called.
Parameters:
Name
Type
Description
token_root
address
Token root address of the token that is transferred
tokens_amount
uint128
Amount of the token to be transferred
sender_address
address
Address of the sender account
sender_wallet
address
Sender’s wallet address
original_gas_to
address
Address where to send gas when calling contract’s methods
payload
TvmCell
Additional data about transaction flow

Deposit liquidity

expectedDepositLiquidity

function expectedDpositLiquidity(uint128 left_amount, uint128 right_amount, bool auto_change) override external view responsible returns (DepositLiquidityResult)

expectedDepositLiquidity

function expectedDpositLiquidity(uint128 left_amount, uint128 right_amount, bool auto_change) override external view responsible returns (DepositLiquidityResult)
Called before depositing liquidity in order to calculate the expected deposit liquidity.
  • If liquidity supply is 0 create DepositLiquidityResult with left amount, right amount, max value of left and right amountl.
  • Else calculate it by calling _expectedDepositLiquidity.
Parameters:
Name
Type
Description
left_amount
uint128
Left token amount in liquidity pool
right_amount
uint128
Right token amount in liquidity pool
auto_change
bool
If true automatically deposit to liquidity
Return values:
Type
Description
DepositLiquidityResult

_expectedDepositLiquidity

function _expectedDepositLiquidity(uint128 left_amount, uint128 right_amount, bool auto_change) private view returns (DepositLiquidityResult)
Does the actual calculation for expected deposit liquidity and returns deposit liquidity result. If the left and right amount for depositing are greater than 0, calculate the first deposit for the left and right token and liquidity pool reward and after that calculate current left, right balance and lp supply in order to either continue with the exchange if they are greater than 0, or create deposit results right away. When all checks are done and all values are calculated, DepositLiquidityResult is built and returned as expected.
Parameters:
Name
Type
Description
left_amount
uint128
Left token amount in liquidity pool
right_amount
uint128
Right token amount in liquidity pool
auto_change
bool
If true automatically deposit to liquidity
Return values:
Type
Description
DepositLiquidityResult
Deposit to liquidity pool result

depositLiquidity

function depositLiquidity(uint64 call_id, uint128 left_amount, uint128 right_amount, address expected_lp_root, bool auto_change, address account_owner, uint32 /*account_version*/, address send_gas_to ) override external onlyActive onlyAccount(account_owner)
Calculates and stores data such as liquidity pool supply, left balance, right balance and if it is first deposit to the current pool calls dexPairDepositLiquiditySuccess callback. If not, according to the data retrieved calling _expectedDepositLiquidity changes left and right balance values, calls DexAccount’s InternalPairTransfer if there is need for exchange. When everything is successfully done, mint is started in the dex pair’s root where recipient is account owner and successCallback is called to notify about successful deposit action.
Parameters:
Name
Type
Description
call_id
uint64
ID of the operation call
left_amount
uint128
Left token amount to be deposited in the liquidity pool
right_amount
uint128
Right token amount to be deposited in the liquidity pool
expected_lp_root
address
Root address of the liquidity pool used for depositing
auto_change
bool
If true automatically deposit right and left token
account_owner
address
Address of the account’s owner
account_version
uint32
Current version of the account
send_gas_to
address
Address where to send gas when calling contract’s methods

Withdraw liquidity

_withdrawLiquidityBase

function _withdrawLiquidityBase(uint128 lp_amount) private returns (uint128, uint128)
Reduces right and left balance for the amount that is being withdrawn and reduces the liquidity pool supply for the total value of withdrawal, emits WithdrawLiquidity with lp amount withdrawn and left and right amount taken from the pool.
Parameters:
Name
Type
Description
lp_amount
uint128
Amount to be withdrawn from the liquidity pool
Return values:
Type
Description
uint128
Amount of the left token to be withdrawn
uint128
Amount of the right token to be withdrawn

expectedWithdrawLiquidity

function expectedWithdrawLiquidity(uint128 lp_amount) override external view responsible returns (uint128 expected_left_amount, uint128 expected_right_amount)
Calculates the left and right amount to be withdrawn based on the total value that is requested to be withdrawn.
Parameters:
Name
Type
Description
lp_amount
uint128
Amount to be withdrawn from the liquidity pool
uint128
Amount of the right token to be withdrawn
Return values:
Name
Type
Description
expected_left_amount
uint128
Calculated left token amount to be withdrawn from the liquidity pool
expected_right_amount
uint128
Calculated right token amount to be withdrawn from the liquidity pool

withdrawLiquidity

function withdrawLiquidity(uint64 call_id, uint128 lp_amount, address expected_lp_root, address account_owner, uint32 /*account_version*/, address send_gas_to) override external onlyActive onlyAccount(account_owner)
Calculating and applying new liquidity pool balances and supply after withdrawal, transferring withdrawn amount to DexAccount. If initial required conditions are fulfilled, get left and right amount of tokens to withdraw by calling _withdrawLiquidityBase, call dexPairWithdrawSuccess callback for account owner to notify successful withdrawal. If left and right amount to withdraw are greater than 0 transfer them to the account by calling DexAccount’s internalPairTransfer, burn withdrawn tokens in the specified pool by calling burnTokens method from the IBurnableByRootTokenRoot.
Parameters:
Name
Type
Description
call_id
uint64
ID of the operation call
lp_amount
uint128
Amount to be withdrawn from the liquidity pool
expected_lp_root
address
Root address of the liquidity pool used for withdrawal
account_owner
address
Address of the account’s owner
account_version
uint32
Current version of the account
send_gas_to
address
Address where to send gas when calling contract’s methods

Exchange

expectedExchange

function expectedExchange(uint128 amount, address spent_token_root) override external view responsible returns (uint128 expected_amount, uint128 expected_fee)
Returns the expected exchange amount and exchange fee based on the amount to exchange and token used for exchange by calling the private method _expectedExchange.
Parameters:
Name
Type
Description
amount
uint128
Token amount to be exchanged
spent_token_root
address
Address of the token root which will be exchanged
Return values:
Name
Type
Description
expected_amount
uint128
Calculated exchange amount
expected_fee
uint128
Calculated exchange fee
expectedSpendAmount
function expectedSpendAmount(uint128 receive_amount, address receive_token_root) override external view responsible returns (uint128 expected_amount, uint128 expected_fee)
Returns the expected spend amount and expected fee by calling the private method _expectedSpendAmount based on receive amount and specified token root address
Parameters:
Name
Type
Description
receive_amount
uint128
Token amount to receive after exchange
receive_token_root
address
Token root address of the receiving exchange token
Return values:
Name
Type
Description
expected_amount
uint128
Calculated amount to be spent
expected_fee
uint128
Calculated fee
exchange
function exchange(uint64 call_id, uint128 spent_amount, address spent_token_root, address receive_token_root, uint128 expected_amount, address account_owner, uint32 /*account_version*/, address send_gas_to) override external onlyActive onlyAccount(account_owner)
Swap function between tokens of one liquidity pool, checks in which direction the exchange is initiated and if all the conditions are fulfilled (enough tokens, fees greater than 0, send amount ge expected amount…) balance on sender token side will decrease and balance on the receiver token side will increase.
Parameters:
Name
Type
Description
call_id
uint64
ID of the operation call
spent_amount
uint128
Amount of the spend token to be exchanged for receive token
spent_token_root
address
Address of the token which will be exchanged for receive token
receive_token_root
address
Address of the token for which exchange is happening
expected_amount
uint128
Expected amount of the receive token
account_owner
address
Address of the account which is the exchange initiator
account_version
uint32
Current version of the account
send_gas_to
address
Address where to send gas when calling contract’s methods
_expectedExchange
function _expectedExchange(uint128 a_amount, uint128 a_pool, uint128 b_pool) private view returns (uint128, uint128)
Does the actual calculation for the desired exchange, calculates exchange fee, returns amount of tokens that are exchanged calculated by a special equation and fee for the given exchange token.
Parameters:
Name
Type
Description
a_amount
uint128
Token amount to be exchanged
a_pool
uint128
Total amount of left/right tokens
b_pool
uint128
Total amount of right/left tokens
Type
Description
uint128
Token amount to get after exchange
uint128
Exchange fee
_expectedSpendAmount
function _expectedSpendAmount(uint128 b_amount, uint128 a_pool, uint128 b_pool) private view returns (uint128, uint128)
Calculates the expected spending amount based on the tokens amount that will be taken from exchange, total amount of tokens in the pool of the token that will be given for exchange and total amount of tokens in the pool from which desired tokens will be taken, returns expected amount of tokens that will be given for an exchange and fee for exchange.
Parameters:
Name
Type
Description
b_amount
uint128
Token amount to get after exchange
a_pool
uint128
Total amount of left/right tokens
b_pool
uint128
Total amount of right/left tokens
Return values:
Type
Description
uint128
Token amount to exchange
uint128
Exchange fee

Cross-pair exchange

crossPairExchange
function crossPairExchange( uint64 id, uint32 /*prev_pair_version*/, address prev_pair_left_root, address prev_pair_right_root, address spent_token_root, uint128 spent_amount, address sender_address, address original_gas_to, uint128 deploy_wallet_grams, TvmCell payload) override external onlyPair(prev_pair_left_root, prev_pair_right_root) onlyActive
Checks whether the exchange is happening between pairs of different liquidity pools or between tokens in the same liquidity pool, if it is between lps crossPairExchange is called and if it’s inside of one lp the DexVault’s transfer function is called. If the conditions such as sufficient balance, fees > 0 etc. are not fulfilled, operation is canceled.
Parameters:
Name
Type
Description
id
uint64
ID of the operation call
prev_pair_version
uint32
Current version of the first pair of the cross exchange
prev_pair_left_root
address
Left token root address of the first pair of the cross exchange
prev_pair_right_root
address
Right token root address of the first pair of the cross exchange
spent_token_root
address
Token root address which will be exchanged
spent_amount
uint128
Amount of the token to be exchanged
sender_address
address
Address of the account which is the cross exchange initiator
original_gas_to
address
Address where to send gas when calling contract’s methods
deploy_wallet_grams
uint128
Fee for deploying wallet
payload
TvmCell
Additional data about next exchange in row

Account operations

checkPair
function checkPair(address account_owner, uint32 /*account_version*/) override external onlyAccount(account_owner)
Calls DexAccount’s checkPairCallbeck to check weather the pair exists if not, deploys wallets for each side of the token pair and lp root if it doesn’t exist.
Parameters:
Name
Type
Description
account_owner
address
Address of the account which is the exchange initiator
account_version
uint32
Current version of the account

Code upgrade

upgrade
function upgrade(TvmCell code, uint32 new_version, address send_gas_to) override external onlyRoot
Upgrades pair to a newer version and builds tokens, liquidity tokens, balances, fees, wallets, vault wallets with new upgraded data, calls onCodeUpgrade from new code
Parameters:
Name
Type
Description
code
TvmCell
Code to be set for upgraded version
new_version
uint32
New version value
send_gas_to
address
Address where to send gas when calling contract’s methods
onCodeUpgrade
function onCodeUpgrade(TvmCell upgrade_data) private
Private method used in Upgrade, resets storage, creates new TvmSlice instance and fills it by calling upgrade_data, loads and decodes from slice data such as left, right root, vault address, root address, old version number, current version, send gas to address, after that checks if old version is 0
  • If it is, initializes fee params, adds liquidity to a new dex pair by calling DexVault’s addLiquidityToken.
  • If not sets pool to active, load and decodes lp supply, left, right balance, fee params, lp wallet, left and right wallet and vault’s left and right wallet
Parameters:
Name
Type
Description
upgrade_data
TvmCell
Cell containing all the data about certain DexAccount that should be replaced after upgrading
_configureTokenRootWallets
function _configureTokenRootWallets(address token_root) private view
Using address deploys new wallet and if token root is not equal to the lp root return wallet whose owner is vault.
Parameters:
Name
Type
Description
token_root
address
Address of the token root
onTokenWallet
function onTokenWallet(address wallet) external
Configure wallet based on the sender’s role (left root/right root/lp root) and if non of the wallets included in the lp pool are empty set wallet to active.
Parameters:
Name
Type
Description
wallet
address
Address of the token wallet
onVaultTokenWallet
function onVaultTokenWallet(address wallet) external
If sender is either right or left root and based on which root it is if one of those vault wallets are not configured, the wallet address from the function params will be passed as vault wallet address.
Parameters:
Name
Type
Description
wallet
address
Address of the vault’s wallet
liquidityTokenRootDeployed
function liquidityTokenRootDeployed(address lp_root_, address send_gas_to) override external onlyVault
Configures token root wallets for lp root, left token root and right token root, calls DexRoot’s onPairCreated callback that notifies that the pair is created.
Parameters:
Name
Type
Description
lp_root_
address
Address of the liquidity pool
send_gas_to
address
Address where to send gas when calling contract’s methods
liquidityTokenRootNotDeployed
function liquidityTokenRootNotDeployed(address /*lp_root_*/, address send_gas_to) override external onlyVault
Returns gas to the deployer address, it is used by DexVault’s onLiquidityTokenNotDeployed.
Parameters:
Name
Type
Description
lp_root_
address
Address of the liquidity pool
send_gas_to
address
Address where to send gas when calling contract’s methods

Key Events

PairCodeUpgraded

PairCodeUpgraded(uint32 version);
Emitted when pair code upgrades.

FeesParamsUpdated

FeesParamsUpdated(uint16 numerator, uint16 denominator);
Emitted when numerator and denominator value gets updated.

DepositLiquidity

DepositLiquidity(uint128 left, uint128 right, uint128 lp);
Emitted when liquidity is deposited.

WithdrawLiquidity

WithdrawLiquidity(uint128 lp, uint128 left, uint128 right);
Emitted when withdrawing liquidity.

ExchangeLeftToRight

ExchangeLeftToRight(uint128 left, uint128 fee, uint128 right);
Emitted whenever left token to right token exchange occurs.

ExchangeRightToLeft

ExchangeRightToLeft(uint128 right, uint128 fee, uint128 left);
Emitted whenever right token to left token exchange occurs.
Copy link
Outline
Getters
getRoot
getTokenRoots
getTokenWallets
getVersion
getVault
getVaultWallets
setFeeParams
getFeeParams
isActive
getBalances
Direct operations
buildExchangePayload
buildDepositLiquidityPayload
buildWithdrawLiquidityPayload
buildCrossPairExchangePayload
onAcceptTokenTransfer
Deposit liquidity
expectedDepositLiquidity
expectedDepositLiquidity
_expectedDepositLiquidity
depositLiquidity
Withdraw liquidity
_withdrawLiquidityBase
expectedWithdrawLiquidity
withdrawLiquidity
Exchange
expectedExchange
Cross-pair exchange
Account operations
Code upgrade
Key Events
PairCodeUpgraded
FeesParamsUpdated
DepositLiquidity
WithdrawLiquidity
ExchangeLeftToRight
ExchangeRightToLeft