Creating New Pools

InitiaDEX allows anyone to create a liquidity pool.

public entry fun create_pair_script(
    creator: &signer,
    name: String,
    symbol: String,
    swap_fee_rate: Decimal128,
    coin_a_weight: Decimal128,
    coin_b_weight: Decimal128,
    coin_a_metadata: Object<Metadata>,
    coin_b_metadata: Object<Metadata>,
    coin_a_amount: u64,
    coin_b_amount: u64,
)
ParameterDescription
nameName of the trading pair and the corresponding LP Token
symbolSymbol for the LP Token
swap_fee_rateFee rate applied to swaps
coin_a_weight and coin_b_weightBalancer weights for the respective coins
coin_a_metadata and coin_b_metadataMetadata for each coin in the pair
coin_a_amount and coin_b_amountInitial amounts for each coin

For more information on metadata, please refer to obtaining metadata.

initiad tx move execute 0x1 dex create_pair_script \
    --args '["string:name", "string:symbol", "bigdecimal:0.001", "bigdecimal:0.8", "bigdecimal:0.2", "object:0x...", "object:0x...", "u64:100", "u64:100"]' \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

How to Provide Liquidity

Provide Liquidity

provide_liquidity enables the users to provide liquidity of both coin_a and coin_b in the specific pair. In order to maximize liquidity, the user should provide in resonation with the current ratio. The Move module interface is as follows:

public entry fun provide_liquidity_script(
    account: &signer,
    pair: Object<Config>,
    coin_a_amount_in: u64,
    coin_b_amount_in: u64,
    min_liquidity: Option<u64>
)
  • pair: The metadata or object address of pair.
  • coin_a_amount_in and coin_b_amount_in: Amount of token provided for coin_a and coin_b.
  • min_liquidity: Minimum amout of liquidity token to receive. In case that the actual value is smaller than min_liquidity, the transaction will fail.
initiad tx move execute 0x1 dex provide_liquidity_script \
    --args '["object:0x...", "u64:100", "u64:100", "option<u64>:100"]' \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

Single Asset Provide Liquidity

Instead of creating a pair, the user can provide a pool of only one token. Internally, the token will be swapped to another token and provide liquidity, so there can be fee and slippage in occurance. The Move function interface is as follows:

public entry fun single_asset_provide_liquidity_script(
    account: &signer,
    pair: Object<Config>,
    provide_coin: Object<Metadata>,
    amount_in: u64,
    min_liquidity: Option<u64>
)
  • pair: The metadata or object address of pair.
  • provide_coin: The metadata of the provided coin.
  • amount_in: The amount of provided coin.
  • min_liquidity: Minimum amout of liquidity token to receive. In case that the actual value is smaller than min_liquidity, the transaction will fail.
initiad tx move execute 0x1 dex single_asset_provide_liquidity_script \
    --args '["object:0x...", "object:0x..", "u64:100", "option<u64>:100"]' \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

How to Withdraw Liquidity

Withdraw Liquidity

withdraw_liquidity allows users to provide liquidity tokens and receive coin_a and coin_b. The Move module interface is as follows:

public entry fun withdraw_liquidity_script(
    account: &signer,
    pair: Object<Config>,
    liquidity: u64,
    min_coin_a_amount: Option<u64>,
    min_coin_b_amount: Option<u64>,
)
  • pair: The metadata or object address of pair.
  • liquidity: Amount of liquidity token.
  • min_coin_a_amount and min_coin_b_amount : Minimum amout of coin_a or coin_b to receive. In case that the actual value is smaller than min_coin_a_amount or min_coin_b_amount, the transaction will fail.
initiad tx move execute 0x1 dex withdraw_liquidity_script \
    --args '["object:0x...", "u64:100", "option<u64>:100", "option<u64>:100"]' \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

How to Swap Pair

Swap Simulation

swap_simulation is a view function to estimate the return value of said swap.

#[view]
/// Return swap simulation result
public fun get_swap_simulation(
    pair: Object<Config>,
    offer_metadata: Object<Metadata>,
    offer_amount: u64,
): u64 // return amount
  • pair: The metadata or object address of pair.
  • offer_metadata: Metadata of offered coin.
  • offer_amount: Amount of offered coin.
curl -X POST "[LCD_URI]/initia/move/v1/accounts/0x1/modules/dex/view_functions/get_swap_simulation" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -d "{ \"args\": [ \"[BCS_ENCODED_OBJECT, BCS_ENCODED_OBJECT, BCS_ENCODED_OFFER_AMOUNT]\" ]}"

#{
#  "data": "\"100\"",
#  "events": [],
#  "gas_used": "5699"
#}

Swap

The Move module interface for swap function is as follows:

public entry fun swap_script(
    account: &signer,
    pair: Object<Config>,
    offer_coin: Object<Metadata>,
    offer_coin_amount: u64,
    min_return: Option<u64>,
)
  • pair: The metadata or object address of pair.
  • offer_coin: Metadata of offered coin.
  • offer_coin_amount: Amount of offered coin.
  • min_return: Minimum return amount of coin. In case that the actual value is smaller than min_return, the transaction will fail.
initiad tx move execute 0x1 dex swap_script \
    --args '["object:0x...", "object:0x...", "u64:100", "option<u64>:100"]' \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

How to Delegate LP Tokens

Whitelist a Pair

To delegate your LP tokens to a validator, you need to whitelist the LP token first. We can use MsgWhitelist to whitelist the LP token.

proposal.json
{
  "messages": [
    {
      "@type": "/initia.move.v1.MsgWhitelist",
      "authority": "init10d07y265gmmuvt4z0w9aw880jnsr700j55nka3",
      "metadata_lp": "init1law8gy5hj9mvtelssjnvg0amudfyn0y42kv4v04q4yl30pevmm2qhvvk8v",
      "reward_weight": "1000000000000000000"
    }
  ],
  "deposit": "100000000uinit",
  "metadata": "uinit",
  "summary": "it is awesome",
  "title": "awesome proposal"
}
initiad tx gov submit-proposal proposal.json \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

Delegate LP Tokens

After whitelisting the LP token, you can delegate your LP tokens to a validator. We can use MsgDelegate to delegate LP tokens.

# initiad tx mstaking delegate [validator-addr] [amount]
initiad tx mstaking delegate initvaloper1.... 100move/ff5c7412979 \
    --from [key-name] \
    --gas auto --gas-adjustment 1.5 --gas-prices 0.15uinit \
    --node [rpc-url]:[rpc-port] --chain-id [chain-id]

Example Code

The following example demonstrates the above functions in a single script using InitiaJS.

The script includes the following steps:

  1. Create a pair
  2. Provide liquidity
  3. Whitelist LP
  4. Delegate LP tokens to the validator
  5. Withdraw rewards from the validator

To run the script, you need to install the following packages:

npm install @initia/initia.js @initia/initia.proto @noble/hashes @cosmjs/encoding bluebird

Also, we assume:

  • Local Initia node is running on http://localhost:1317.
  • The user and validator share the same mnemonic for simplicity.