Module dex.move
This module implements a DEX between an arbitrary token pair, using the Balancer price curve specialized for pools containing two assets. The module also maintains a centralized registry for all pools, enabling easier discovery of trading pools.
The module implements several convenience functions that simplify its usage. Some functions, identified by the _script
suffix, are intended as convenience functions that implement some common usage patterns, particularly useful to simplify scripts. These and other trivial functions are not explicitly included in this threat model description as they do not perform any security checks that affect the underlying DEX operation. This does not mean that the helper functions do not perform any security check at all; for instance, swap_script
includes a check on the output amount, which needs to be performed manually when using the lower-level swap
function. However, this check can indeed be implemented by the caller of swap
and is not fundamentally required for the correct operation of the DEX. We note that not all convenience functions are suffixed with _script
(as is the case for provide_liquidity_from_coin_store
).
Function: get_spot_price
This function can be used to compute the spot price for a given pair, in either trade direction. Note that (by design) the spot price is not the effective price of a trade, as it only represents the correct price for an infinitesimally small trade.
Inputs
pair: Object<Config>
Validation: Must refer to an existing pool.
Impact: Identifies the pool.
base_coin: Object<Metadata>
Validation: Must refer to one of the two assets contained in the pool.
Impact: Determines the base asset for the spot price.
Function: update_swap_fee_rate
This function can only be invoked by the special @initia_std
address. It can be used to set the swap fee rate for a given trading pair. Note that this is the only function that allows to change the swap fee rate for a pool. The initial swap fee rate is set by the creator of the pair at the time of its creation.
Inputs
chain: &signer
Validation: Must be
@initia_std
.Impact: Used to authorize the operation.
pair: Object<Config>
Validation: No validation required.
Impact: Identifies the pool to modify.
swap_fee_rate: Decimal128
Validation: Must be at most
MAX_FEE_RATE
(5%).Impact: New swap fee rate to set.
Function: withdraw_liquidity
This function can be used to redeem pool tokens for the corresponding amount of the pool assets. The function can only be invoked on pools that are not in a bootstrapping phase.
Inputs
lp_token: FungibleAsset
Validation: Must (implicitly) correspond to the address of a pool.
Impact: Input LP tokens to redeem.
min_coin_a_amount: Option<u64>
Validation: None required.
Impact: If specified, the amount of A asset returned by redeeming the LP tokens must be greater than this amount.
min_coin_b_amount: Option<u64>
Validation: None required.
Impact: If specified, the amount of B asset returned by redeeming the LP tokens must be greater than this amount.
Function: single_asset_provide_liquidity
This function can be used to add liquidity to the pool by supplying only one of the two pool assets. This is effectively implemented as a balanced swap of some of the single-sided liquidity for a corresponding amount of the other asset, followed by a normal balanced liquidity injection. Note that the swap does incur fees, which prevents using this function as a workaround to not be charged for swapping assets.
The function can only be called on pools that are not in the liquidity bootstrapping period.
Inputs
pair: Object<Config>
Validation: None explicitly required.
Impact: Identifies the pool to which liquidity is to be added.
provide_coin: FungibleAsset
Validation: Must be one of the two pool assets.
Impact: Fungible asset to add to the pool liquidity.
min_liquidity_amount: Option<u64>
Validation: None required.
Impact: If provided, the amount of pool LP tokens returned is required to be greater than this.
Function: swap
This function can be used to perform a swap. This is the lowest-level publicly accessible function, used by several other convenience functions.
The function can only be called on pools that are not in the liquidity bootstrapping period.
Inputs
pair: Object<Config>
Validation: None explicitly required.
Impact: Identifies the pool where the swap occurs.
offer_coin: FungibleAsset
Validation: Must be one of the two pool assets.
Impact: Input asset for the swap.
Function: create_pair
This function can be used to create a new pool.
Inputs
creator: &signer
Validation: None required.
Impact: Creator of the pool.
name: String
Validation: None (could be unrelated to the pool assets and thus misleading).
Impact: Name of the pool.
symbol: String
Validation: None (could be unrelated to the pool assets and thus misleading).
Impact: Symbol for the pool.
swap_fee_rate: Decimal128
Validation: Must be less than 5%.
Impact: Swap fee rate.
coin_a: FungibleAsset
Validation: Must be different from
coin_b
.Impact: First asset of the pool pair.
coin_b: FungibleAsset
Validation: Must be different from
coin_a
.Impact: Second asset of the pool pair.
weights: Weights
Validation: None.
Impact: Weights for the pool assets.
Function: provide_liquidity
This function can be used to provide liquidity to the pool. The function is intended to provide balanced liquidity, and any imbalanced amount will be effectively donated to the pool.
Inputs
pair: Object<Config>
Validation: None required.
Impact: Determines the pool where liquidity is to be added.
coin_a: FungibleAsset
Validation: Must be the first asset in the pool pair (only implicitly checked).
Impact: First asset to add to the pool liquidity.
coin_b: FungibleAsset
Validation: Must be the second asset in the pool pair (only implicitly checked).
Impact: Second asset to add to the pool liquidity.
min_liquidity_amount: Option<u64>
Validation: None required.
Impact: If provided, the program asserts the liquidity returned is at least this amount.
Function: swap_simulation
This function can be used to simulate a swap, given an input amount, reserve amounts, and pool parameters (asset weights and swap fee rate). Note that while this function is read only on its own, it is also used by the actual swap
function to compute the result of a swap (output amount received and fees paid).
Inputs
pool_amount_in: u64
Validation: N/A.
Impact: Amount of the input-asset pool reserves.
pool_amount_out: u64
Validation: N/A.
Impact: Amount of the output-asset pool reserves.
weight_in: Decimal128
Validation: N/A.
Impact: Weight of the input asset.
weight_out: Decimal128
Validation: N/A.
Impact: Weight of the output asset.
amount_in: u64
Validation: N/A.
Impact: Amount of input asset provided for the swap.
swap_fee_rate: Decimal128
Validation: N/A.
Impact: Swap fee rate.
Function: swap_simulation_given_out
This function can be used to simulate a swap. Unlike swap_simulation
, this function receives the desired output amount and computes the required input amount and the fees to be paid.
Inputs
pool_amount_in: u64
Validation: N/A.
Impact: Amount of the input-asset pool reserves.
pool_amount_out: u64
Validation: N/A.
Impact: Amount of the output-asset pool reserves.
weight_in: Decimal128
Validation: N/A.
Impact: Weight of the input asset.
weight_out: Decimal128
Validation: N/A.
Impact: Weight of the output asset.
amount_in: u64
Validation: N/A.
Impact: Desired amount of output asset.
swap_fee_rate: Decimal128
Validation: N/A.
Impact: Swap fee rate.