Programs
PumpSwap (AMM)
The constant-product AMM that graduated coins migrate into, including effective quote reserves.
PumpSwap program is a constant-product AMM deployed at address pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA on
both Mainnet
and Devnet.
State
GlobalConfig
The global configuration of the program is stored in the only GlobalConfig account, whose address is
ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw (PDA-derived from ["global_config"] seeds). The content of this account
can be examined
on Mainnet Solscan:
{
"admin": {
"type": "pubkey",
"data": "FFWtrEQ4B4PKQoVuHYzZq8FabGkVatYzDpEVHsK5rrhF"
},
"lp_fee_basis_points": {
"type": "u64",
"data": "20"
},
"protocol_fee_basis_points": {
"type": "u64",
"data": "5"
},
"disable_flags": {
"type": "u8",
"data": 0
},
"protocol_fee_recipients": {
"type": {
"array": [
"pubkey",
8
]
},
"data": [
"62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV",
"7VtfL8fvgNfhz17qKRMjzQEXgbdpnHHHQRh54R9jP2RJ",
"7hTckgnGnLQR6sdH7YkqFTAA7VwTfYFaZ6EhEsU3saCX",
"9rPYyANsfQZw3DnDmKE3YCQF5E8oD89UXoHn9JFEhJUz",
"AVmoTthdrX6tKt4nDjco2D775W2YK3sDhxPcMmzUAmTY",
"FWsW1xNtWscwNmKv6wVsU1iTzRN6wmmk3MjxRP5tT7hz",
"G5UZAVbAf46s7cKWoyKu8kYTip9DGTpbLZ2qa9Aq69dP",
"JCRGumoE9Qi5BBgULTgdgTLjSgkCMSbF62ZZfGs84JeU"
]
}
}
- The
adminpubkey is the pubkey authorized to update theGlobalConfigaccount. - The
lp_fee_basis_points == 20 bpsandprotocol_fee_basis_points == 5 bpsare the fees charged by the AMM for eachbuy/sellinstruction. No fees are charged ondeposit/withdrawinstruction. - The
disable_flagsis a bitmask that can be used to disable certain instructions. Currently, it is not used. - The
protocol_fee_recipientsis an array of 8 pubkeys which receive the protocol fees on eachbuy/sellinstruction. Any of the 8 pubkeys can be used in abuy/sellinstruction and it is recommended to randomly choose a different one for eachbuy/sellinstruction to improve program tx throughput.
Pool
Each pool is represented by a Pool account, which is PDA-derived from the
["pool", index, creator, baseMint, quoteMint] seeds. An example Pool account data can be found
at https://solscan.io/account/GseMAnNDvntR5uFePZ51yZBXzNSn7GdFPkfHwfr6d77J#accountData:
{
"pool_bump": {
"type": "u8",
"data": 254
},
"index": {
"type": "u16",
"data": "0"
},
"creator": {
"type": "pubkey",
"data": "9XDYTfQKwW8sHPqnFdUreMmtmffmkHVPGTNV2e3LKxNW"
},
"base_mint": {
"type": "pubkey",
"data": "7LSsEoJGhLeZzGvDofTdNg7M3JttxQqGWNLo6vWMpump"
},
"quote_mint": {
"type": "pubkey",
"data": "So11111111111111111111111111111111111111112"
},
"lp_mint": {
"type": "pubkey",
"data": "6dpnPD6UWDw5hbJEuPQwnCCMba1JYwHANKuL6GQ6otAH"
},
"pool_base_token_account": {
"type": "pubkey",
"data": "5jMpkf4JF4noHftLgNKyPNh6roVfPSGSjuEk3U4eLKRa"
},
"pool_quote_token_account": {
"type": "pubkey",
"data": "43DVcZR4kQFjh4Xm2i3DcneRxNjZp7HMud8yDrJWrDr8"
},
"lp_supply": {
"type": "u64",
"data": "4194352106721"
},
"coin_creator": {
"type": "pubkey",
"data": "5L5k7gtNLbeXdzpvNrFshg1E1id1ceUDfc6vPUTxp98q"
},
"is_mayhem_mode": {
"type": "bool",
"data": false
},
"is_cashback_coin": {
"type": "bool",
"data": false
},
"virtual_quote_reserves": {
"type": "i128",
"data": "0"
}
}
- The
pool_bumpis the bump seed used to derive the pool PDA. - The
indexis the index of the pool, which is used to derive the pool PDA. PumpSwap pools created using Pump programmigrateinstruction use aCANONONICAL_POOL_INDEX == 0. - The
creatoris the pubkey of the pool creator, which is also used to derive the pool PDA. - The
base_mintandquote_mintare the mint addresses of the base and quote tokens of the pool. - The
lp_mintis the mint address of the LP token, which is used to represent the liquidity of the pool. The LP mint address can also be PDA-derived from the["pool_lp_mint", pool_key]seeds, but it is stored inPoolaccount for simpler pubkey equality checks on PumpSwap program instructions. - The
pool_base_token_accountandpool_quote_token_accountare the ATAs (associated token accounts) of the base and quote mints of thepoolaccount, respectively. They again could be PDA-derived from thepool,base_mintandquote_mintpubkeys, but they are stored in thePoolaccount for easier pubkey equality checks on PumpSwap program instructions. - The
lp_supplyis the total supply of thelp_mintwithout burns and lock-ups. This means that if someone deposits into the pool, then they burn theirlp_minttokens, thePool::lp_supplywill still reflect the original supply of thelp_mint. This way, the pool differentiates betweenlp_minttokens burnt by users directly and those burnt by thewithdrawinstruction. - The
coin_creatoris the pubkey that accrues the coin-creator fees for this pool (see PUMP_SWAP_CREATOR_FEE_README). On pools that predate coin-creator fees it isPubkey::default()(11111111111111111111111111111111). - The
is_mayhem_modeflag indicates whether the pool operates in mayhem mode. - The
is_cashback_coinflag indicates whether the coin's creator fee is routed as cashback (see PUMP_CASHBACK_README). - The
virtual_quote_reserves(i128) is an additional (appended) quote-reserve amount that a pool may carry. Quotes must be computed against the pool's effective quote reserves, not the raw quote-vault token balance, see Quoting: effective quote reserves. It is0on all pools today, so effective quote reserves currently equal the raw vault balance; some pools may carry a non-zero value in the future.
Quoting: effective quote reserves
Buys and sells are priced on the pool's effective quote reserves, which are the raw quote-vault token balance plus
Pool::virtual_quote_reserves:
effective_quote_reserves = pool_quote_token_account.amount + Pool::virtual_quote_reserves
- Use
effective_quote_reserves(not the rawpool_quote_token_account.amount) wherever you quote, price, or index a pool, for bothbuyandsell. virtual_quote_reservesis0on all pools today, so effective quote reserves equal the raw vault balance and quotes are unchanged. Integrating against effective quote reserves now is safe and keeps your quotes correct if a pool later carries a non-zerovirtual_quote_reserves.- The base side is unchanged: base reserves are still the raw
pool_base_token_account.amount.
Indexers: the BuyEvent and SellEvent logs include virtual_quote_reserves (appended field), so effective quote
reserves can be reconstructed directly from the event stream.
Instructions
It supports the following Anchor program instructions:
-
create_pool(index, creator, baseMint, quoteMint, baseIn, quoteIn).- This allows creating a new AMM pool for the
(baseMint, quoteMint)pair. - The
poolIdis PDA-derived from the tuple(index, creator, baseMint, quoteMint). Theindexallows the samecreatorto create multiple pools for the same(baseMint, quoteMint)pair. - The
creatoris the pubkey of the pool creator and also the payer for pool creation costs. baseInandquoteInare the initial amounts ofbaseMintandquoteMinttokens to be deposited into the pool, and they determine the initial pool price.- The
creatoralso receives somelpMinttokens, which represent the initial liquidity of the pool. TheselpMinttokens can be later used towithdrawliquidity from the pool.
- This allows creating a new AMM pool for the
-
Liquidity instructions:
deposit(pool, user, lpTokenOut, maxBaseIn, maxQuoteIn)allows auserto deposit at mostmaxBaseInandmaxQuoteIntokens into thepoolin order to get exactlylpTokenOuttokens in return.withdraw(pool, user, lpTokenIn, minBaseOut, minQuoteOut)allows auserto withdraw at leastminBaseOutandminQuoteOuttokens from thepoolby burning exactlylpTokenIntokens in return.
-
Swap instructions:
buy(pool, user, baseOut, maxQuoteIn)allows auserto buy exactlybaseOuttokens from thepoolby paying at mostmaxQuoteIntokens.sell(pool, user, baseIn, minQuoteOut)allows auserto sell exactlybaseIntokens to thepoolto receive at leastminQuoteOuttokens.
-
Utility instructions:
extend_account(user, account)allows any user to extend the data array of a program-owned account (GlobalConfigorPoolaccount) to allow for future fields to be added to those account types.
-
Admin instructions (can be executed only to
GlobalConfig::adminpubkey):create_config(hardcoded_admin, global_config)allows creating the soleGlobalConfigaccount on initial PumpSwap program deployment. Thehardcoded_adminis a hardcoded pubkey into PumpSwap program itself, which is allowed to create theGlobalConfigaccount and will initializeGlobalConfig::adminto thehardcoded_adminpubkey. This instruction can be run only once, because it will fail the second time, sinceGlobalConfigalready exists.disable(admin, disable_create_pool, disable_deposit, disable_withdraw, disable_buy, disable_sell)allows theadminto globally disable any Pump Swap operation.update_admin(admin, new_admin, global_config)allows theadminto update theGlobalConfig::adminpubkey to a new one.update_fee_config(admin, lp_fee_basis_points, protocol_fee_basis_points, protocol_fee_recipients)allows theadminto update theGlobalConfig::lp_fee_basis_points,GlobalConfig::protocol_fee_basis_pointsandGlobalConfig::protocol_fee_recipients.
Mapping PumpSwap SDK methods to Anchor instructions
-
PumpAmmAdminSdk.createPoolInstructions(index, creator, baseMint, quoteMint, baseIn, quoteIn)returns acreate_pool(index, creator, baseMint, quoteMint, baseIn, quoteIn)instruction. -
PumpAmmAdminSdk.depositInstructions(pool, user, lpTokenOut, slippage)returns adeposit(pool, user, lpTokenOut, maxBaseIn, maxQuoteIn)instruction, wheremaxBaseInandmaxQuoteInare computed usinglpTokenOut,slippageand the current pool balances. -
PumpAmmAdminSdk.withdrawInstructions(pool, user, lpTokenIn, slippage)returns awithdraw(pool, user, lpTokenIn, minBaseOut, minQuoteOut)instruction, whereminBaseOutandminQuoteOutare computed usinglpTokenIn,slippageand the current pool balances. -
PumpAmmInternalSdk.buyBaseInput(pool, user, baseOut, slippage)returns abuy(pool, user, baseOut, maxQuoteIn)instruction, wheremaxQouteInis computed usingbaseOut,slippageand the current pool balances. -
PumpAmmInternalSdk.buyQuoteInput(pool, user, quote, slippage)returns abuy(pool, user, baseOut, maxQuoteIn)instruction, wherebaseOutis computed usingquote,slippageand the current pool balances andmaxQuoteInisquotescaled withslippage. -
PumpAmmInternalSdk.sellBaseInput(pool, user, baseIn, slippage)returns asell(pool, user, baseIn, minQuoteOut)instruction, whereminQuoteOutis computed usingbaseIn,slippageand the current pool balances. -
PumpAmmInternalSdk.sellQuoteInput(pool, user, quote, slippage)returns asell(pool, user, baseIn, minQuoteOut)instruction, wherebaseInis computed usingquote,slippageand the current pool balances andminQuoteOutisquotescaled withslippage. -
PumpAmmSdk.swapBaseInstructions(pool, user, base, slippage, direction)calls eitherPumpAmmInternalSdk.buyBaseInput(pool, user, base, slippage)(if (direction == "quoteToBase")) orPumpAmmInternalSdk.sellBaseInput(pool, user, base, slippage)(if (direction == "baseToQuote")). -
PumpAmmSdk.swapQuoteInstructions(pool, user, quote, slippage, direction)calls eitherPumpAmmInternalSdk.buyQuoteInput(pool, user, quote, slippage)(if (direction == "quoteToBase")) orPumpAmmInternalSdk.sellQuoteInput(pool, user, quote, slippage)(if (direction == "baseToQuote")).
PumpSwap SDK autocomplete UI helpers
Each Anchor instruction has a set of corresponding autocomplete methods that can be used to autocomplete the UI inputs:
-
PumpAmmSdk.createAutocompleteInitialPoolPrice(initialBase, initialQuote)is used to display the initial pool price based on the initialbaseandquoteinputs on pool creation. -
PumpAmmSdk.depositAutocompleteQuoteAndLpTokenFromBase(pool, base, slippage)is used to autocomplete the correspondingquoteandlpTokenvalues in the UI when thebaseinput changes on deposit UI. -
PumpAmmSdk.depositAutocompleteBaseAndLpTokenFromQuote(pool, quote, slippage)is used to autocomplete the correspondingbaseandlpTokenvalues in the UI when thequoteinput changes on deposit UI. -
PumpAmmSdk.swapAutocompleteBaseFromQuote(pool, quote, slippage, swapDirection)is used to autocomplete the correspondingbasevalue in the UI when thequoteinput changes on swap UI. -
PumpAmmSdk.swapAutocompleteQuoteFromBase(pool, base, slippage, swapDirection)is used to autocomplete the correspondingquotevalue in the UI when thebaseinput changes on swap UI. -
PumpAmmSdk.swapAutocompleteBaseFromQuote(pool, quote, slippage, swapDirection)calls eitherPumpAmmInternalSdk.buyAutocompleteBaseFromQuote(pool, quote, slippage)(if (swapDirection == "quoteToBase")) orPumpAmmInternalSdk.sellAutocompleteBaseFromQuote(pool, quote, slippage)(if (swapDirection == "baseToQuote")). -
PumpAmmSdk.swapAutocompleteQuoteFromBase(pool, base, slippage, swapDirection)calls eitherPumpAmmInternalSdk.buyAutocompleteQuoteFromBase(pool, base, slippage)(if (swapDirection == "quoteToBase")) orPumpAmmInternalSdk.sellAutocompleteQuoteFromBase(pool, base, slippage)(if (swapDirection == "baseToQuote")). -
PumpAmmSdk.withdrawAutoCompleteBaseAndQuoteFromLpToken(pool, lpToken, slippage)is used to autocomplete the correspondingbaseandquotevalues in the UI when thelpTokeninput changes on withdraw UI.
Mirrored from PUMP_SWAP_README.md in the official docs repository.