Skip to content

DEX module API

Paul edited this page Nov 29, 2023 · 22 revisions

Asset Conversion embedded module

There is an embedded Substrate DEX module called Asset Conversion implemented into the "Ledger of Things" runtime, which allows to swap one on-chain asset to another by means of a constant product formula. The pallet is based on Uniswap V2 logic.

Overview

The module API allows to:

  • create a liquidity pool for 2 assets
  • provide liquidity to the pool in exchange for its LP (Liquidity Pool) token
  • exchange the LP token back for the asset (or native coin) liquidity has been provided with
  • swap 2 assets for one another
  • query for the exchange price via the runtime call endpoint
  • query for the liquidity pool size

API

1. Extrinsic 'assetConversion.createPool'

This method allows to create a liquidity pool for a couple of assets, each of which could be either an on-chain asset (a token issued on The Ledger of Things by the poscanAssets module or the native currency P3D. The associated new lp_token asset will be created as well (the id of the LP token is returned in the Event::PoolCreated event).

createPool(
        asset1, 
        asset2
)
  • asset1: - pick up the asset id Asset: u32 on poscanAssets module storage or Native for P3D
  • asset2: - Asset: u32 or Native (for P3D)

2. Extrinsic 'assetConversion.addLiquidity'

This method allows to add liquidity to the pool actually created and get its share in the LP tokens.

addLiquidity(
         asset1, 
         asset2, 
         amount1Desired, 
         amount2Desired, 
         amount1Min, 
         amount2Min,
         mintTo
)
  • asset1: - on-chain asset id AssetId: u32 on poscanAssets module storage or Native (for P3D)
  • asset2: - on-chain asset id AssetId: u32 or Native (for P3D)
  • amount1Desired: u128 - the amount of the asset 1 desired to provide (NOTE: an optimal amount will be calculated and might be different)
  • amount2Desired: u128 - the amount of the asset 2 desired to provide (NOTE: an optimal amount will be calculated and might be different)
  • amount1Min: u128 - min amount of the asset 1 you would be happy to provide
  • amount2Min: u128 - min amount of the asset 2 you would be happy to provide
  • mintTo: AccountId32 - P3D account to send LP tokens to (the liquidity pool share)

3. Extrinsic 'assetConversion.removeLiquidity'

This method allows to remove liquidity out of the pool and get the share (in the LP tokens) burnt.

removeLiquidity(
             asset1, 
             asset2, 
             lpTokenBurn, 
             amount1MinReceive, 
             amount2MinReceive, 
             withdrawTo
)
  • asset1: - on-chain asset id AssetId: u32 on poscanAssets module storage or Native (for P3D)
  • asset2: - on-chain asset id AssetId: u32 or Native (for P3D)
  • lpTokenBurn: u128 - amount of the LP tokens to burn
  • amount1MinReceive: u128 - amount of the asset 1 tokens you would be happy to receive (the actual amount will be calculated during the process)
  • amount2MinReceive: u128 - amount of the asset 2 tokens you would be happy to receive (the actual amount will be calculated during the process)
  • withdrawTo: AccountId32 - P3D account to withdraw

4. Extrinsic 'assetConversion.swapExactTokensForTokens'

This method allows to swap a certain amount of tokens of the asset 1 into the asset 2 (the amount of tokens to receive will be calculated during the swap).

swapExactTokensForTokens(
            path, 
            amountIn, 
            amountOutMin, 
            sendTo, 
            keepAlive
)
  • path: - the path for the swap (from 0 to 1)
    • 0: AssetId: u32 on poscanAssets module storage or Native (for P3D)
    • 1: AssetId: u32 or Native (for P3D)
  • amountIn: u128 - a certain amount of tokens you give
  • amountOutMin: u128 - minimum amount of tokens you would be happy to receive
  • sendTo: AccountId32 - P3D account to receive
  • keepAlive: bool - preserves the min amount of tokens on sender's account to keep it alive after the transfer

5. Runtime Call 'quote_price_exact_tokens_for_tokens'

Provides a quote for swapExactTokensForTokens

quote_price_exact_tokens_for_tokens(
    &self,
    __runtime_api_at_param__: <Block as BlockT>::Hash,
    asset1: AssetId,
    asset2: AssetId,
    amount: AssetBalance,
    include_fee: bool
) -> Result<Option<Balance>, ApiError>

Note that the price may have changed by the time the transaction is executed. (Use amount_out_min to control slippage.)

6. Extrinsic 'swap_tokens_for_exact_tokens'

This method allows to swap some tokens of the asset 1 (the amount of tokens to send will be calculated during the swap) into a certain amount of tokens of the asset 2.

swapTokensForExactTokens(
           path, 
           amountOut, 
           amountInMax, 
           sendTo, 
           keepAlive
)
  • path: - the path for the swap (from 0 to 1)
    • 0: AssetId: u32 on poscanAssets module storage or Native (for P3D)
    • 1: AssetId: u32 or Native (for P3D)
  • amountOut: u128 - a certain amount of tokens to receive
  • amountInMax: u128 - the max amount of tokens you would be happy to give
  • sendTo: AccountId32 - P3D account to receive
  • keepAlive: bool - preserves the min amount of tokens on sender's account to keep it alive after the transfer

7. Runtime call 'quote_price_tokens_for_exact_tokens'

Provides a quote for swap_tokens_for_exact_tokens

quote_price_tokens_for_exact_tokens(
    &self,
    __runtime_api_at_param__: <Block as BlockT>::Hash,
    asset1: AssetId,
    asset2: AssetId,
    amount: AssetBalance,
    include_fee: bool
) -> Result<Option<Balance>, ApiError>

Note that the price may have changed by the time the transaction is executed. (Use amount_in_max to control slippage.)