Astroport
Search…
πŸ’±
Swap Pairs
The Astroport marketplace where anyone can trade their wares

1. Overview

At launch, Astroport will only support two pool types:
  • Stableswap Invariant Pools
  • Constant Product Pools
Depending on your use-cases and needs as well as the types of assets you want to integrate, one of these pools will be better than the other.
The contract code for the constant product pool can be found here and the code for the stableswap invariant pool is here.

2. Walkthrough

The following are examples and descriptions of core functions that can be called by anyone to provide and withdraw liquidity as well as to simulate swaps and query Astroport pairs.

Providing Liquidity

Before calling the provide_liquidity function, users will have to approve the pool to take tokens from their wallets.
provide_liquidity
When an address executes the provide_liquidity operation, it provides liquidity by sending a user's native or token assets to the pool.
The provide_liquidity operation takes in the following parameters:
Params
Description
assets: [Asset; 2]
The type of assets in the pool. Can include a CW-20 contract_addr or a native_token denomination
slippage_tolerance: Option <Decimal>
The slippage tolerance for providing liquidity. Ensures that the LP transaction goes through only if the price in the pool moves less than the specified tolerance
auto_stake: Option <Bool>
Determines whether the newly minted LP tokens are also staked in the Generator contract in the same transaction
receiver: Option <String>
The receiver of the newly minted LP tokens

Providing Liquidity Without Specifying Slippage Tolerance

The provide_liquidity operation, along with most operations in this walkthrough, works in the same way for both constant product and stableswap pools. This tutorial will use the ANC-UST Astroport pair for constant product pools and the bLUNA-LUNA Astroport pair for stableswap pools.
ANC-UST
bLUNA-LUNA
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uusd"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
}
22
}
Copied!
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uluna"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
}
22
}
Copied!

Providing Liquidity With Slippage Tolerance

slippage_tolerance is an object of type [`Option<Decimal>`]. It is used to specify how much the pool price can move until the provided liquidity transaction goes through.
ANC-UST
bLUNA-LUNA
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uusd"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
"slippage_tolerance": "0.01",
22
}
23
}
Copied!
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uluna"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
"slippage_tolerance": "0.01",
22
}
23
}
Copied!

Single-sided Liquidity Provision in Stableswap Pools

Liquidity providers can single side LP in stableswap pools (add only one of the tokens). LPs need to call the provide_liquidity function and set the amount for one of the pair tokens to "0". This can only be done for pools that already have liquidity (not for empty pools).
bLUNA-LUNA
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uluna"
16
}
17
},
18
"amount": "0"
19
}
20
],
21
"slippage_tolerance": "0"
22
}
23
}
Copied!

Receiver & Autostake

The receiver and auto_stake parameters are optional as well.
receiveris an object of type [`Option<String>`]. Calling the provide_liquidity operation with a custom receiver allows you to specify where to send the resulting LP tokens. If no custom receiver is specified, the pair will mint LP tokens for the function caller.
auto_stake is an object of type [`Option<Bool>`]. Calling the provide_liquidity operation with auto_stake astrue allows LP tokens to automatically be staked in the Generator contract (if the LP tokens currently get ASTRO or 3rd party emissions). If auto_stake is not specified, LP tokens will just be minted for the recipient.
ANC-UST
bLUNA-LUNA
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uusd"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
"slippage_tolerance": "0.01",
22
"auto_stake": true,
23
"receiver": "terra..."
24
}
25
}
Copied!
1
{
2
"provide_liquidity": {
3
"assets": [
4
{
5
"info": {
6
"token": {
7
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
8
}
9
},
10
"amount": "1000000"
11
},
12
{
13
"info": {
14
"native_token": {
15
"denom": "uluna"
16
}
17
},
18
"amount": "1000000"
19
}
20
],
21
"slippage_tolerance": "0.01",
22
"auto_stake": true,
23
"receiver": "terra..."
24
}
25
}
Copied!

Withdrawing Liquidity

withdraw_liquidity

The withdraw_liquidity operation burns LP tokens and withdraws liquidity from a pool.
1
{
2
"withdraw_liquidity": {}
3
}
Copied!
pair
The withdraw_liquidity operation must be sent to the LP token contract associated with the pool from which you want to withdraw liquidity. You can find the associated LP token contract for a given pool by calling the pair query in the Astroport pair contract.
Query
ANC-UST Response
bLUNA-LUNA Response
1
{
2
"pair": {}
3
}
Copied!
1
{
2
"asset_infos": [
3
{
4
"token": {
5
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
6
}
7
},
8
{
9
"native_token": {
10
"denom": "uusd"
11
}
12
}
13
],
14
"contract_addr": "terra1qr2k6yjjd5p2kaewqvg93ag74k6gyjr7re37fs",
15
"liquidity_token": "terra1wmaty65yt7mjw6fjfymkd9zsm6atsq82d9arcd",
16
"pair_type": {
17
"xyk": {}
18
}
19
}
Copied!
1
{
2
"asset_infos": [
3
{
4
"token": {
5
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
6
}
7
},
8
{
9
"native_token": {
10
"denom": "uluna"
11
}
12
}
13
],
14
"contract_addr": "terra1j66jatn3k50hjtg2xemnjm8s7y8dws9xqa5y8w",
15
"liquidity_token": "terra1htw7hm40ch0hacm8qpgd24sus4h0tq3hsseatl",
16
"pair_type": {
17
"stable": {}
18
}
19
}
Copied!
receive
The pool will process the withdraw_liquidity function through the receive operation which receives a message and processes it depending on the receiving template.
1
{
2
"receive": {
3
"sender": "terra...",
4
"amount": "123",
5
"msg": "<base64_encoded_json_string>"
6
}
7
}
Copied!

Simulations & Reverse Simulations

simulation

The simulation query for a given Astroport Pair contract simulates a swap and returns the spread and commission amounts. The query takes in an offer_asset which can include a CW-20 contract_addr or a native_token denomination depending on the pair.

Constant Product Pairs

In the case of the ANC-UST Astroport Pair, we can query simulation and specify the offer_asset as either a CW-20 contract_addr for ANC or a native_token denomination for UST.
The query returns a return_amount with the latest exchange rate for the pool, along with the spread_amount, and the commission_amount.
UST Query
UST Ex. Response
ANC Query
ANC Ex. Response
1
{
2
"simulation": {
3
"offer_asset": {
4
"info": {
5
"native_token": {
6
"denom": "uusd"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"return_amount": "364661",
3
"spread_amount": "0",
4
"commission_amount": "1097"
5
}
Copied!
1
{
2
"simulation": {
3
"offer_asset": {
4
"info": {
5
"token": {
6
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"return_amount": "2740085",
3
"spread_amount": "0",
4
"commission_amount": "8244"
5
}
Copied!

Stableswap Pairs

The simulation query works the same for stableswap pools. In the case of the bLUNA-LUNA Astroport Pair, we can specify the offer_asset as either a CW-20 contract_addr for bLUNA or a native_token denomination for LUNA.
bLUNA Query
bLUNA Ex. Response
LUNA Query
LUNA Ex. Response
1
{
2
"simulation": {
3
"offer_asset": {
4
"info": {
5
"token": {
6
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"return_amount": "971560",
3
"spread_amount": "27954",
4
"commission_amount": "486"
5
}
Copied!
1
{
2
"simulation": {
3
"offer_asset": {
4
"info": {
5
"native_token": {
6
"denom": "uluna"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"return_amount": "1028274",
3
"spread_amount": "0",
4
"commission_amount": "514"
5
}
Copied!

reverse_simulation

The reverse_simulation query for a given Astroport Pair contract reverse simulates a swap (specifies the ask instead of the offer) and returns the spread and commission amounts. The query takes in an offer_asset which can include a CW-20 contract_addr or a native_token denomination depending on the pair.

Constant Product Pairs

In the case of the ANC-UST Astroport Pair, we can query reverse_simulation and specify the ask_asset as either a CW-20 contract_addr for ANC or a native_token denomination for UST.
The query returns an offer_amount with the latest exchange rate for the pool, along with the spread_amount, and the commission_amount.
UST Query
UST Ex. Response
ANC Query
ANC Ex. Response
1
{
2
"reverse_simulation": {
3
"ask_asset": {
4
"info": {
5
"native_token": {
6
"denom": "uusd"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"offer_amount": "363810",
3
"spread_amount": "0",
4
"commission_amount": "3009"
5
}
Copied!
1
{
2
"reverse_simulation": {
3
"ask_asset": {
4
"info": {
5
"token": {
6
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"offer_amount": "2768715",
3
"spread_amount": "0",
4
"commission_amount": "3009"
5
}
Copied!

Stableswap Pairs

The reverse_simulation query works the same for stableswap pools. In the case of the bLUNA-LUNA Astroport Pair, we can specify the ask_asset as either a CW-20 contract_addr for bLUNA or a native_token denomination for LUNA.
bLUNA Query
bLUNA Ex. Response
LUNA Query
LUNA Ex. Response
1
{
2
"reverse_simulation": {
3
"ask_asset": {
4
"info": {
5
"token": {
6
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"offer_amount": "973473",
3
"spread_amount": "0",
4
"commission_amount": "500"
5
}
Copied!
1
{
2
"reverse_simulation": {
3
"ask_asset": {
4
"info": {
5
"native_token": {
6
"denom": "uluna"
7
}
8
},
9
"amount": "1000000"
10
}
11
}
12
}
Copied!
1
{
2
"offer_amount": "1028279",
3
"spread_amount": "27779",
4
"commission_amount": "500"
5
}
Copied!
share
Similar to the simulation and reserve_simulation queries, the share query accepts an amount of LP tokens and returns information about the share of the pool represented by that LP token amount. The query can be used to simulate the amount of assets someone would get from the pool if they were to burn a specific amount of LP tokens.
Query
ANC-UST Ex. Response
bLUNA-LUNA Ex. Response
1
{
2
"share": {
3
"amount": "123"
4
}
5
}
Copied!
1
[
2
{
3
"info": {
4
"token": {
5
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
6
}
7
},
8
"amount": "74"
9
},
10
{
11
"info": {
12
"native_token": {
13
"denom": "uusd"
14
}
15
},
16
"amount": "205"
17
}
18
]
Copied!
1
[
2
{
3
"info": {
4
"token": {
5
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
6
}
7
},
8
"amount": "140"
9
},
10
{
11
"info": {
12
"native_token": {
13
"denom": "uluna"
14
}
15
},
16
"amount": "106"
17
}
18
]
Copied!

Querying Data

config
The stableswap invariant algorithm uses an amplification parameter A that determines how close the stableswap curve should be to the constant product curve; an amplification value of 0 (A = 0) achieves results identical to the constant product pool algorithm; higher values of A push the curve closer to the constant price curve, resulting in lower slippage for exchange rates close to 1:1.
To fetch the current amplification for a stableswap pool, an address can call the config query on the associated Astroport pair contract for the pool. config returns control settings including a key-value pair of params and a base64 encoded string. In the case of the bLUNA-LUNA pair, the encoded base64 string returns an amp of 10.
Query
Ex. Response
Ex. base64
1
{
2
"config": {}
3
}
Copied!
1
{
2
"block_time_last": 1645679032,
3
"params": "eyJhbXAiOiIxMCJ9"
4
}
Copied!
1
{"amp":"10"}
Copied!
pair
To determine whether a given pool is a Constant Product ("xyk") or a Stableswap ("stable") pool, an address can call the pair query on a given Astroport pair contract. The query returns the pair_type along with additional information, such as the asset_infos for the pool, the contract_addr, and the liquidity_token address.
Query
ANC-UST Ex. Response
bLUNA-LUNA Response
1
{
2
"pair": {}
3
}
Copied!
1
{
2
"asset_infos": [
3
{
4
"token": {
5
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
6
}
7
},
8
{
9
"native_token": {
10
"denom": "uusd"
11
}
12
}
13
],
14
"contract_addr": "terra1qr2k6yjjd5p2kaewqvg93ag74k6gyjr7re37fs",
15
"liquidity_token": "terra1wmaty65yt7mjw6fjfymkd9zsm6atsq82d9arcd",
16
"pair_type": {
17
"xyk": {}
18
}
19
}
Copied!
1
{
2
"asset_infos": [
3
{
4
"token": {
5
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
6
}
7
},
8
{
9
"native_token": {
10
"denom": "uluna"
11
}
12
}
13
],
14
"contract_addr": "terra1j66jatn3k50hjtg2xemnjm8s7y8dws9xqa5y8w",
15
"liquidity_token": "terra1htw7hm40ch0hacm8qpgd24sus4h0tq3hsseatl",
16
"pair_type": {
17
"stable": {}
18
}
19
}
Copied!

pool

An address can query the pool operation to return the amount of tokens in the pool for all assets as well as the amount of LP tokens issued.
Query
ANC-UST Ex. Response
bLUNA-LUNA Response
1
{
2
"pool": {}
3
}
Copied!
1
{
2
"assets": [
3
{
4
"info": {
5
"token": {
6
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
7
}
8
},
9
"amount": "36268222716042"
10
},
11
{
12
"info": {
13
"native_token": {
14
"denom": "uusd"
15
}
16
},
17
"amount": "141697076440565"
18
}
19
],
20
"total_share": "70924668725349"
21
}
Copied!
1
{
2
"assets": [
3
{
4
"info": {
5
"token": {
6
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
7
}
8
},
9
"amount": "2721079925472"
10
},
11
{
12
"info": {
13
"native_token": {
14
"denom": "uluna"
15
}
16
},
17
"amount": "2100156386627"
18
}
19
],
20
"total_share": "2401981675336"
21
}
Copied!

share

An address can query the share operation to return the amount of assets someone would get from the pool if they were to burn a specific amount of LP tokens.
Query
ANC-UST Ex. Response
bLUNA-LUNA Response
1
{
2
"share": {
3
"amount": "123"
4
}
5
}
Copied!
1
[
2
{
3
"info": {
4
"token": {
5
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
6
}
7
},
8
"amount": "62"
9
},
10
{
11
"info": {
12
"native_token": {
13
"denom": "uusd"
14
}
15
},
16
"amount": "245"
17
}
18
]
Copied!
1
[
2
{
3
"info": {
4
"token": {
5
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
6
}
7
},
8
"amount": "139"
9
},
10
{
11
"info": {
12
"native_token": {
13
"denom": "uluna"
14
}
15
},
16
"amount": "107"
17
}
18
]
Copied!

cumulative_prices

An address the cumulative_prices operation to return the cumulative prices for the assets in the pair.
Query
ANC-UST Ex. Response
bLUNA-LUNA Response
1
{
2
"cumulative_prices": {}
3
}
Copied!
1
{
2
"assets": [
3
{
4
"info": {
5
"token": {
6
"contract_addr": "terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76"
7
}
8
},
9
"amount": "36268094868278"
10
},
11
{
12
"info": {
13
"native_token": {
14
"denom": "uusd"
15
}
16
},
17
"amount": "141698574941565"
18
}
19
],
20
"total_share": "70924918241920",
21
"price0_cumulative_last": "15459045753406",
22
"price1_cumulative_last": "2691791013087"
23
}
Copied!
1
{
2
"assets": [
3
{
4
"info": {
5
"token": {
6
"contract_addr": "terra1kc87mu460fwkqte29rquh4hc20m54fxwtsx7gp"
7
}
8
},
9
"amount": "2721045270406"
10
},
11
{
12
"info": {
13
"native_token": {
14
"denom": "uluna"
15
}
16
},
17
"amount": "2100190225363"
18
}
19
],
20
"total_share": "2401981675336",
21
"price0_cumulative_last": "5940818942668",
22
"price1_cumulative_last": "6095129954262"
23
}
Copied!

fee_info

To determine the fee charged on swaps for a specific pool and the division of profits from fees between LPs and governance, an address can call the fee_info query on the Astroport Factory contract.
The query takes in a pair_type and returns the fee_address (Maker contract), the total_fee_bps, and the maker_fee_bps.In the case of Constant Product pools like ANC-UST, the total fee is 0.3% with 2/3 going to LPs and 1/3 to governance.
With a 1% slippage tolerance, amountUSTMin (the minimum amount of UST to LP) should be set to 198 UST, and amountASSETMin (the minimum amount of ASSET to LP) should be set to .99 ASSET. This means that, in a worst case scenario, liquidity will be added at a pool rate of 198 ASSET/1 UST or 202.02 UST/1 ASSET (200 UST + .99 ASSET).
Constant Product
Stableswap
Non-Boosted
Ex. Response
1
{
2
"fee_info": {
3
"pair_type": {
4
"xyk": {}
5
}
6
}
7
}
Copied!
1
{
2
"fee_info": {
3
"pair_type": {
4
"stable": {}
5
}
6
}
7
}
Copied!
1
{
2
"fee_info": {
3
"pair_type": {
4
"custom": "XYK-2BPS"
5
}
6
}
7
}
Copied!
1
{
2
"fee_address": "terra12u7hcmpltazmmnq0fvyl225usn3fy6qqlp05w0",
3
"total_fee_bps": 30,
4
"maker_fee_bps": 3333
5
}
Copied!

3. Notes on Slippage

Liquidity Provision

If an LP specifies a slippage tolerance when providing liquidity (either in a Constant Product or a Stableswap pool), the pool contract makes sure that the transaction goes through only if the pool price does not change more than the tolerance.
As an example, let's say someone LPs in a pool and specifies a 1% slippage tolerance. The user LPs 200 UST and 1 ASSET.
With a 1% slippage tolerance, amountUSTMin (the minimum amount of UST to LP) should be set to 198 UST, and amountASSETMin (the minimum amount of ASSET to LP) should be set to .99 ASSET. This means that, in a worst case scenario, liquidity will be added at a pool rate of 198 ASSET/1 UST or 202.02 UST/1 ASSET (200 UST + .99 ASSET).
If the contract cannot add liquidity within these bounds (because the pool ratio changed more than the tolerance), the transaction will revert.

Trading

Astroport has two options to protect traders against slippage during swaps:
  1. 1.
    Provide max_spread - the spread is calculated as the difference between the ask amount (using the constant pool price) before and after the swap operation. Once max_spread is set, it will be compared against the actual swap spread. In case the swap spread exceeds the provided max limit, the swap will fail. Note that the spread is calculated before commission deduction in order to properly represent the pool's ratio change
  2. 2.
    Provide max_spread + belief_price - if belief_price is provided in combination with max_spread, the pool will check the difference between the return amount (using belief_price) and the real pool price
  3. 3.
    Provide max_spread - the spread is calculated as the difference between the ask amount (using the constant pool price) before and after the swap operation. Once max_spread is set, it will be compared against the actual swap spread. In case the swap spread exceeds the provided max limit, the swap will fail. Note that the spread is calculated before commission deduction in order to properly represent the pool's ratio change
  4. 4.
    Provide max_spread + belief_price - if belief_price is provided in combination with max_spread, the pool will check the difference between the return amount (using belief_price) and the real pool price
Please note that Astroport has the default value for the spread set to 0.5% and the max allowed spread set to 50%.