sell

Sell launchpad tokens back to the pool for SOL or WSOL. Supports exact-in (sell X tokens, receive ≥ Y quote) and exact-out (receive exactly Y quote, sell ≤ X tokens), applies protocol/creator fees, updates pool state, and emits a structured trade log (log_trade_internal) for indexers.

Program: Tradersdex Curve (Launchpad) Instruction: sell Emits: TradeEvent via internal log_trade_internal Pool status required: LIVE


Modes & Pool Types

Trade modes

Mode
Semantics

Exact-in (is_exact_in = true)

Sell exact token_amount; must receive min_sol_out (after fees)

Exact-out (is_exact_in = false)

Receive exact min_sol_out (after fees); must sell token_amount

Pool types (on-chain pool_type)

Value
Quote
Creator fee?

0 (Basic)

SOL

1 (WithCreator)

SOL

2 (WithCustomQuote)

WSOL

3 (Full)

WSOL

QuoteVault rule:

  • WSOL pools (2/3): quote_vault = ATA(NATIVE_MINT, pool)

  • SOL pools (0/1): quote_vault = pool (lamports held on pool PDA)


Arguments


Accounts

#
Name
Writable
Seeds / Constraints
Description

0

pool

["pool", mint], owner = program

Pool PDA; custom-deserialized

1

mint

Sale token mint

2

quote_mint

For WSOL must be NATIVE_MINT

For SOL may be Pubkey::default()

3

token_vault

ATA(mint, pool)

Pool base token vault

4

quote_vault

WSOL: ATA(NATIVE_MINT, pool) • SOL: pool

Pool quote holding

5

user_token_account

ATA(mint, payer)

Seller’s token ATA (source)

6

user_quote_account

WSOL: ATA(NATIVE_MINT, payer)

Seller’s WSOL ATA (dest)

7

fee_recipient

Must equal one of PDA(["protocol_fee_vault",[i]])

Protocol fee receiver

8

payer

Seller

9

token_program

= anchor_spl::token::ID

SPL Token

10

associated_token_program

For ATA ops

11

system_program

For SOL transfers

12

tradersdex_curve

= crate::ID

Self-check

13

event_authority

["event_authority"]

Signs inner log ix

14

token_creator

Must equal pool creator for fee pools

Creator pubkey

15

token_creator_ata

ATA(NATIVE_MINT, token_creator)

Needed to activate creator fee (WSOL path)


Behavior

  • Math

    • Uses virtual reserves vr_quote, vr_token.

    • Exact-in (sell X tokens):

      • Gross quote out (before fee): gross = floor(tokens_in * vr_quote / (vr_token + tokens_in))

      • Fees are output-side: total_fee = ceil(gross * fee_bps / 10000)

      • Net to user: net = gross - total_fee (must be min_sol_out)

    • Exact-out (receive exact Y quote after fees):

      • gross = ceil( net * 10000 / (10000 - fee_bps) )

      • Tokens required: tokens_in = floor(gross * vr_token / (vr_quote - gross))

      • Must satisfy tokens_in ≤ token_amount

  • Indexer

    • Emits inner log_trade_internal with is_buy = false and updated fields.


TypeScript: build the sell instruction (no send)

This helper derives all accounts and returns the TransactionInstruction for sell. It applies your quoteVault rule automatically.


Usage

Exact-in (sell X tokens, receive ≥ Y quote):

Exact-out (receive exactly Y quote, sell ≤ X tokens):


Indexer: log_trade_internal

Every successful sell triggers an internal instruction with:

Field
Type
Description

pool

Pubkey

Pool address

trader

Pubkey

Seller

mint

Pubkey

Token mint

sol_amount

u64

Net SOL/WSOL to seller (after fees)

token_amount

u64

Tokens sold (debited from seller)

fee_amount

u64

Total fee (protocol + creator) on output

creator_fee

u64

Creator fee portion

protocol_fee

u64

Protocol fee portion

is_buy

bool

false for sell

vr_quote / vr_token

u64

Updated virtual reserves

raised_quote / sold_supply

u64

Updated totals

timestamp

i64

Block time (seconds)


Troubleshooting

  • InvalidWsolAccount (WSOL pools): ensure

    • quote_mint == NATIVE_MINT

    • quote_vault == ATA(NATIVE_MINT, pool)

    • user_quote_account == ATA(NATIVE_MINT, payer)

    • For creator-fee pools, token_creator_ata == ATA(NATIVE_MINT, token_creator) (and initialized to activate creator fee)

  • InvalidFeeRecipient: derive one of protocol_fee_vault[i].

  • SlippageExceeded: raise min_sol_out tolerance (exact-in) or increase token_amount cap (exact-out).

  • InsufficientLiquidity: pool doesn’t have enough quote to pay out (SOL path checks pool lamports; WSOL path checks quote_vault balance).

Last updated