The Pool Manager is a contract that handles liquidity pools in the MANTRA DEX. It facilitates the creation and management of different pool types, liquidity provision, swaps, and multi-hop operations across pools.
Pool creation is permissionless (a fee is required to prevent spam). Multiple pools can exist for the same asset pair, each with a unique identifier.
Pool types
There are two pool types: constant product (XYK) and stableswap.
XYK Pool
The XYK pool uses a constant product invariant:
XY=k
Where X and Y are the reserves for each token, and k is constant.
XY=k=(X+Δx)(Y−Δy)
To determine the ask asset amount (\Delta y) given the offered asset (\Delta x):
Δy=fracYDeltaxX+Deltax
The spread between executed and expected trade is:
spread=(YDeltax/X)−(YDeltax/(X+Deltax))
Stableswap
Implements the StableSwap curve described by Curve: https://curve.fi/files/stableswap-paper.pdf.
Supports 2–4 assets and is designed for low slippage stable-asset trading.
Instantiate
{
"fee_collector_addr": "mantra1...",
"farm_manager_addr": "mantra1...",
"pool_creation_fee": {
"denom": "uom",
"amount": "1000000000"
}
}
| Key | Type | Description |
|---|
fee_collector_addr | String | Fee collector contract address. |
farm_manager_addr | String | Farm manager contract address. |
pool_creation_fee | Coin | Cost to create a pool. |
ExecuteMsg
CreatePool
Creates a new pool with assets, decimals, fees, pool type, and identifier.
Pool identifiers:
- Auto-assigned pools get prefix
p. (e.g. p.1)
- Custom identifiers get prefix
o. (e.g. o.my_pool)
XYK example
{
"create_pool": {
"asset_denoms": ["uom", "uusdc"],
"asset_decimals": [6, 6],
"pool_fees": {
"protocol_fee": { "share": "0.001" },
"swap_fee": { "share": "0.002" },
"burn_fee": { "share": "0" },
"extra_fees": [{ "share": "0.001" }]
},
"pool_type": "constant_product",
"pool_identifier": "uom.uusdy.pool"
}
}
Stableswap example
{
"create_pool": {
"asset_denoms": ["uusdt", "uusdc"],
"asset_decimals": [6, 6],
"pool_fees": {
"protocol_fee": { "share": "0.0002" },
"swap_fee": { "share": "0.0003" },
"burn_fee": { "share": "0" },
"extra_fees": []
},
"pool_type": { "stable_swap": { "amp": 85 } },
"pool_identifier": "uusdt.uusdc.pool"
}
}
| Key | Type | Description |
|---|
asset_denoms | Vec<String> | Asset denoms. |
asset_decimals | Vec<u8> | Decimals for each denom (same order as asset_denoms). |
pool_fees | PoolFee | Pool fees. |
pool_type | PoolType | Constant product or stableswap. |
pool_identifier | Option<String> | Pool identifier (optional). |
ProvideLiquidity
Provides liquidity to a pool. If lock_position_identifier is set, LP tokens are locked in the farm manager for the specified duration; otherwise they are sent to the receiver.
It’s only possible to lock an LP position for the same user providing liquidity (not on behalf of another user).
{
"provide_liquidity": {
"slippage_tolerance": "0.01",
"max_spread": "0.1",
"receiver": "mantra1...",
"pool_identifier": "uom.uusdy.pool",
"unlocking_duration": 2678400,
"lock_position_identifier": "lp.lock.identifier"
}
}
| Key | Type | Description |
|---|
slippage_tolerance | Option<Decimal> | Max acceptable slippage. |
max_spread | Option<Decimal> | Max spread allowed. |
receiver | Option<String> | Receiver of LP tokens. |
pool_identifier | String | Pool identifier. |
unlocking_duration | Option<u64> | Duration (seconds) for farm lock/unlock behavior. |
lock_position_identifier | Option<String> | Position identifier to lock (if any). |
Swap
Swaps an offer asset to an ask asset in a specific pool. Offer amount is provided in info.funds.
{
"swap": {
"ask_asset_denom": "uusdc",
"belief_price": "0.5",
"max_spread": "5000",
"receiver": "mantra1...",
"pool_identifier": "uom.uusdy.pool"
}
}
| Key | Type | Description |
|---|
ask_asset_denom | String | Return asset denom. |
belief_price | Option<Decimal> | Belief price. |
max_spread | Option<Decimal> | Maximum spread. |
receiver | Option<String> | Recipient (defaults to sender). |
pool_identifier | String | Pool identifier. |
WithdrawLiquidity
Withdraws liquidity from a pool. LP tokens must be sent with the transaction.
{
"withdraw_liquidity": {
"pool_identifier": "uom.uusdy.pool"
}
}
| Key | Type | Description |
|---|
pool_identifier | String | Pool identifier. |
ExecuteSwapOperations
Executes multiple swap operations (multi-hop). Routes are computed off-chain.
{
"execute_swap_operations": {
"operations": [
{
"mantra_swap": {
"token_in_denom": "uluna",
"token_out_denom": "uom",
"pool_identifier": "uluna_uom_pool"
}
},
{
"mantra_swap": {
"token_in_denom": "uom",
"token_out_denom": "uusdc",
"pool_identifier": "uom.uusdy.pool"
}
}
],
"minimum_receive": "1000000",
"receiver": "mantra1...",
"max_spread": "0.1"
}
}
| Key | Type | Description |
|---|
operations | Vec<SwapOperation> | Operations in order. |
minimum_receive | Option<Uint128> | Minimum amount received. |
receiver | Option<String> | Final recipient. |
max_spread | Option<Decimal> | Max spread per swap. |
UpdateConfig
{
"update_config": {
"fee_collector_addr": "mantra1...",
"farm_manager_addr": "mantra1...",
"pool_creation_fee": { "denom": "uom", "amount": "1000000000" },
"feature_toggle": {
"withdrawals_enabled": true,
"deposits_enabled": true,
"swaps_enabled": true
}
}
}
UpdateOwnership (::cw_ownable)
This is a cw_ownable message.
QueryMsg
Config
AssetDecimals
{
"asset_decimals": {
"pool_identifier": "om-usdc-1",
"denom": "uom"
}
}
Simulation
{
"simulation": {
"offer_asset": { "denom": "uom", "amount": "1000000" },
"ask_asset_denom": "uusdc",
"pool_identifier": "om-usdc-1"
}
}
ReverseSimulation
{
"reverse_simulation": {
"ask_asset": { "denom": "uusdc", "amount": "990000" },
"offer_asset_denom": "uom",
"pool_identifier": "om-usdc-1"
}
}
SimulateSwapOperations / ReverseSimulateSwapOperations
See legacy examples in _tmp_gitbook/mantra-smart-contracts/mantra-swap/pool-manager.md (ported here verbatim in structure).
Pools
{
"pools": {
"pool_identifier": "om-usdc-1",
"start_after": null,
"limit": 10
}
}
Ownership (::cw_ownable)
This is a cw_ownable query.
MigrateMsg