Swap Base Out

Swaps tokens by specifying the output amount.

Instruction

SwapInstructionBaseOut {
    max_amount_in: u64,
    amount_out: u64,
}

Parameters

Parameter
Type
Description

max_amount_in

u64

Maximum acceptable input token amount (slippage protection)

amount_out

u64

Desired amount of output token

Account Setup

#
Account
Description
Derivation

1

Token program

SPL Token program

TOKEN_PROGRAM_ID

2

AMM info

AMM account

[program.toBuffer(), marketId.toBuffer(), "amm_associated_seed"]

3

AMM authority

AMM authority PDA

[Buffer.from("amm authority")]

4

AMM coin vault

Coin token vault

[program.toBuffer(), marketId.toBuffer(), "coin_vault_associated_seed"]

5

AMM PC vault

PC token (SOL) vault

[program.toBuffer(), marketId.toBuffer(), "pc_vault_associated_seed"]

6

User source

Source token account

Depends on swap direction

7

User destination

Destination token account

Depends on swap direction

8

User source owner

Transaction signer (User wallet)

-

9

Coin mint

Coin token mint

Provided by user

10

Platform tax WSOL account

Platform fee account

Platform WSOL address

11

CC* contribution WSOL account

Community fund WSOL

Associated account for fee destination

12

CC* contribution token account

Community fund token

Associated account for fee destination

  • CC - Community Contribution

Function Logic

  1. Verifies the transaction is signed by the token owner

  2. Checks that the AMM is in a valid state for swapping

  3. Determines swap direction (Coin2PC or PC2Coin) based on input and output token accounts

  4. Calculates required input amount before fees using constant product formula

  5. Adjusts input amount to account for fees

  6. Verifies the required input is less than the maximum specified (slippage check)

  7. For SC Bonding Curve tokens, calculates fee distribution among:

    • Platform fee

    • Community contribution (community fund)

    • Token burning

  8. Executes the swap with appropriate fee handling based on token type and swap direction

  9. Updates AMM state data with swap information

Notes

  • Swap Base Out is useful when a user wants an exact output amount

  • Fee calculation differs based on token type and the token's configuration

  • For SC Bonding Curve tokens, fees are distributed according to the token's specified parameters

  • Burns are executed immediately during the swap transaction

  • This function performs more complex calculations than Swap Base In due to working backwards from the desired output

Swap Direction Setup

For selling tokens for SOL (Coin2PC):

  • User source = User's token account: getAssociatedTokenAddress(tokenMint, userWallet, false)

  • User destination = User's SOL account: getAssociatedTokenAddress(NATIVE_MINT, userWallet, false)

For buying tokens with SOL (PC2Coin):

  • User source = User's SOL account: getAssociatedTokenAddress(NATIVE_MINT, userWallet, false)

  • User destination = User's token account: getAssociatedTokenAddress(tokenMint, userWallet, false)

Example Usage

// Derive AMM accounts
const [ammAuthority] = PublicKey.findProgramAddressSync(
  [Buffer.from("amm authority")],
  COOLDEX_PROGRAM_ID
)

const [ammId] = PublicKey.findProgramAddressSync(
  [
    COOLDEX_PROGRAM_ID.toBuffer(),
    marketId.toBuffer(),
    Buffer.from("amm_associated_seed"),
  ],
  COOLDEX_PROGRAM_ID
)

const [ammCoinVault] = PublicKey.findProgramAddressSync(
  [
    COOLDEX_PROGRAM_ID.toBuffer(),
    marketId.toBuffer(),
    Buffer.from("coin_vault_associated_seed"),
  ],
  COOLDEX_PROGRAM_ID
)

const [ammPcVault] = PublicKey.findProgramAddressSync(
  [
    COOLDEX_PROGRAM_ID.toBuffer(),
    marketId.toBuffer(),
    Buffer.from("pc_vault_associated_seed"),
  ],
  COOLDEX_PROGRAM_ID
)

// Determine swap direction
const isSelling = true // Change based on swap direction

// User token accounts
const userTokenAccount = getAssociatedTokenAddressSync(tokenMint, wallet.publicKey, false)

const userWsolAccount = getAssociatedTokenAddressSync(
  NATIVE_MINT,
  wallet.publicKey,
  false
)

// Determine source and destination based on swap direction
const [userSource, userDestination] = isSelling
  ? [userTokenAccount, userWsolAccount]
  : [userWsolAccount, userTokenAccount]

// Create instruction data
const data = Buffer.alloc(17)
data.writeUInt8(10, 0) // SwapBaseOut instruction
data.writeBigUInt64LE(maxAmountIn, 1) // Maximum input amount
data.writeBigUInt64LE(amountOut, 9) // Desired output amount

// Community Contribution storage accounts
const commContribStorageWsol = await PublicKey.createWithSeed(
  tokenMint,
  "w",
  TOKEN_PROGRAM_ID
)

const commContribStorageToken = await PublicKey.createWithSeed(
  tokenMint,
  "t",
  TOKEN_PROGRAM_ID
)

const swapBaseOutIx = new TransactionInstruction({
  programId: COOLDEX_PROGRAM_ID,
  keys: [
    { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
    { pubkey: ammId, isSigner: false, isWritable: true },
    { pubkey: ammAuthority, isSigner: false, isWritable: false },
    { pubkey: ammCoinVault, isSigner: false, isWritable: true },
    { pubkey: ammPcVault, isSigner: false, isWritable: true },
    { pubkey: userSource, isSigner: false, isWritable: true },
    { pubkey: userDestination, isSigner: false, isWritable: true },
    { pubkey: wallet.publicKey, isSigner: true, isWritable: false },
    { pubkey: tokenMint, isSigner: false, isWritable: true },
    { pubkey: AMM_FEE_DESTINATION, isSigner: false, isWritable: true },
    { pubkey: commContribStorageWsol, isSigner: false, isWritable: true },
    { pubkey: commContribStorageToken, isSigner: false, isWritable: true },
  ],
  data: data,
})

Last updated