Pools
A pool holds two different assets, NEAR, NEP-141 or NEP-245, and swaps between them. Pool IDs are counted from 0 in the order pools were created.
Kinds of pools
Section titled “Kinds of pools”Public
Section titled “Public”Anyone can add liquidity and gets shares. A public pool is created with its first liquidity, and the creator gets 1018 shares for it, so nobody else can set its starting price. Its fees can never change.
Private
Section titled “Private”The owner, who created it, is the only one who adds and removes liquidity, and can change the fees. The owner can lock the pool, which is final: after that, its liquidity can’t be removed and its fees can’t change. Locking a pool shows traders and holders of a token that its liquidity stays.
Launch
Section titled “Launch”For launching a token. The creator gives the pool all of the new token, and sets an amount of phantom liquidity of the quote asset (often NEAR): liquidity that isn’t there, but sets the starting price as if it were. As people buy, real quote asset comes in. A swap that would take the pool’s quote balance below the phantom liquidity fails, so sellers can only take out quote asset that buyers put in.
Launch pools don’t take or give back liquidity after creation, and their fees can’t change. Their fees are always collected in the quote asset. A launch pool quoted in NEAR can also have a community fee.
Create a pool
Section titled “Create a pool”create_pool takes:
struct CreatePoolArgs { assets: (AssetId, AssetId), fees: FeeConfiguration, pool_type: PoolType, /// Required for public pools, optional for private pools, /// not accepted for launch pools initial_liquidity: Option<(u128, u128)>,}See Types for FeeConfiguration and PoolType, and Fees for what a fee configuration can do.
Attach:
- NEAR for storage, always. What’s left after the storage is sent to your wallet.
- The initial liquidity, exactly. If one of the assets is NEAR, its amount comes out of the same attached NEAR as the storage.
- For a launch pool, the launched token (the second asset), all of it. The first asset is the quote asset, and
pool_typehas the phantom liquidity.
The response is the new pool’s ID, a Borsh u32. This creates a private pool of NEAR and USDT with a 0.3% fee that stays in the pool, and 1 NEAR and 5 USDT of liquidity:
00 asset 0: near01 16 00 00 00 "usdt.tether-token.near" asset 1: nep141:usdt.tether-token.near01 fees: V201 00 00 00 1 receiver01 Pool00 b8 0b 00 00 Fixed(3000), 0.3%00 pool type: PrivateLatest01 initial liquidity: Some00 00 00 a1 ed cc ce 1b c2 d3 00 00 00 00 00 00 1000000000000000000000000 (1 NEAR)40 4b 4c 00 00 00 00 00 00 00 00 00 00 00 00 00 5000000 (5 USDT)It runs after a storage deposit, registering NEAR and USDT, and depositing 1.01 NEAR and 5 USDT, as in this script. near --quiet prints only the result, so the pool ID can be kept for the next calls:
# A private pool of NEAR and USDT with a 0.3% fee that stays in the pool, and# 1 NEAR and 5 USDT of liquidity. The other 0.01 NEAR pays for its storage.# --quiet prints only the result: the ID of the new pool, in Borsh and base64.POOL_ID=$(near --quiet contract call-function as-transaction dex.intear.near dex_call \ json-args '{ "dex_id": "slimedragon.near/xyk", "method": "create_pool", "args": "AAEWAAAAdXNkdC50ZXRoZXItdG9rZW4ubmVhcgEBAAAAAQC4CwAAAAEAAACh7czOG8LTAAAAAAAAQEtMAAAAAAAAAAAAAAAAAA==", "attached_assets": { "near": "1010000000000000000000000", "nep141:usdt.tether-token.near": "5000000" } }' \ prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain send | jq -r .)echo "Created pool $(echo "$POOL_ID" | base64 -d | od -An -tu4)"Read pools
Section titled “Read pools”get_pool takes a pool ID and returns a Borsh Option<PoolView>, None if there’s no such pool. The pool ID that create_pool returned is already the whole argument:
# The pool ID in Borsh is also the whole argument of get_poolnear contract call-function as-read-only dex.intear.near dex_view \ json-args "$(jq -n --arg pool_id "$POOL_ID" '{ "dex_id": "slimedragon.near/xyk", "method": "get_pool", "args": $pool_id }')" \ network-config mainnet nowA PoolView has the pool’s kind, assets and balances, its fees with the protocol fee, and its fee configuration. get_pools returns several, from start_index, and get_pool_count the number of pools. See Methods.
Edit fees
Section titled “Edit fees”The owner of a private pool can replace its fee configuration with edit_fees, which takes the pool ID followed by the new configuration. Attach NEAR if the new configuration adds account receivers, for their storage. This sets the fee to 0.1%:
# The pool ID, followed by the new fee: 0.1% that stays in the poolARGS=$({ echo "$POOL_ID" | base64 -d; echo "AQEAAAABAOgDAAA=" | base64 -d; } | base64)
near contract call-function as-transaction dex.intear.near dex_call \ json-args "$(jq -n --arg args "$ARGS" '{ "dex_id": "slimedragon.near/xyk", "method": "edit_fees", "args": $args, "attached_assets": {} }')" \ prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendLock a private pool
Section titled “Lock a private pool”lock_pool takes the pool ID. Only the owner can lock a pool, and it can’t be unlocked.
near contract call-function as-transaction dex.intear.near dex_call \ json-args "$(jq -n --arg pool_id "$POOL_ID" '{ "dex_id": "slimedragon.near/xyk", "method": "lock_pool", "args": $pool_id, "attached_assets": {} }')" \ prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendPool versions
Section titled “Pool versions”Pools made before Plach’s current version are V1: PrivateV1, PublicV1 and LaunchV1. They work, but V1 private pools can’t be locked or take a V2 fee configuration. pool_needs_upgrade says whether a pool is V1, and upgrade_pool upgrades it to V2. Anyone can upgrade any pool, and pays for the storage it takes, with attached NEAR. Both take the pool ID.
The Latest pool types of create_pool create pools of the current version.