# Sell Token

Sells tokens back to the bonding curve in exchange for SOL.

## Instruction

```rust
SCBondingCurveInstruction::SellToken {
    pda_token_nonce: u8,
    token_to_spend: u64,
    min_sol_to_receive: u64,
    logging_account_bump: u8,
}
```

## Parameters

| Parameter              | Type  | Description                                                    |
| ---------------------- | ----- | -------------------------------------------------------------- |
| `pda_token_nonce`      | `u8`  | Nonce for the token owner PDA                                  |
| `token_to_spend`       | `u64` | Amount of tokens to sell                                       |
| `min_sol_to_receive`   | `u64` | Minimum acceptable SOL amount to receive (slippage protection) |
| `logging_account_bump` | `u8`  | Bump for the logging authority PDA                             |

## Account Setup

| #  | Account               | Description                      | Derivation                                               |
| -- | --------------------- | -------------------------------- | -------------------------------------------------------- |
| 1  | Payer account         | Transaction signer (User wallet) | -                                                        |
| 2  | Token program         | SPL Token program                | `TOKEN_PROGRAM_ID`                                       |
| 3  | Token owner PDA       | Bonding curve account            | `[Buffer.from("token_owner"), mint.toBuffer(), [nonce]]` |
| 4  | Token mint            | Token mint address               | Provided by user                                         |
| 5  | Owner token account   | Token account for PDA            | `getAssociatedTokenAddress(mint, ownerPDA, true)`        |
| 6  | User token account    | User's token account             | `getAssociatedTokenAddress(mint, userWallet, false)`     |
| 7  | Fee account           | Platform fee account             | Fixed address (see Reference section)                    |
| 8  | Program account       | SC bonding curve program         | SC bonding curve program ID                              |
| 9  | Properties account    | Platform configuration           | `[Buffer.from("settings")]`                              |
| 10 | Log authority account | For structured logs              | `[Buffer.from("logging_authority")]`                     |

## Function Logic

1. Verifies the PDA token owner matches the expected PDA for the token mint
2. Retrieves platform fee from properties account (currently 1%)
3. Verifies the token is not finalized or mark as finalized if migration threshold is crossed
4. Checks if trading is closed for the token
5. Calculates expected SOL return amount using the bonding curve formula
6. Verifies expected SOL amount meets minimum specified (slippage check)
7. Updates pool balances in the bonding curve account
8. Transfers tokens from user to the bonding curve
9. Calculates fee amount and deducts from the SOL return
10. Transfers remaining SOL to the user
11. Transfers fee amount to the fee account
12. Records sell data in logs

## Price Calculation

```
sol_amount = pool_sol_balance * token_amount / (pool_token_balance + token_amount)
```

Where:

* `pool_token_balance` = virtual\_token + real\_token
* `pool_sol_balance` = virtual\_sol + real\_sol
* `token_amount` = amount of tokens being sold

## Notes

* The platform fee is deducted from the SOL return amount
* If the sale would leave less than POOL\_MIGRATION\_RESERVES tokens in the pool, the token is marked as finalized
* Once finalized, a token can no longer be traded on the bonding curve

## Example Usage

```javascript
// Derive PDAs and other accounts
const [tokenOwnerPDA, pdaTokenNonce] = PublicKey.findProgramAddressSync(
  [Buffer.from("token_owner"), tokenMint.toBuffer()],
  SC_BONDING_CURVE_PROGRAM_ID
)

const [propertiesAccount] = PublicKey.findProgramAddressSync(
  [Buffer.from("settings")],
  SC_BONDING_CURVE_PROGRAM_ID
)

const [logAuthority, logAuthorityBump] = PublicKey.findProgramAddressSync(
  [Buffer.from("logging_authority")],
  SC_BONDING_CURVE_PROGRAM_ID
)

// Get token accounts
const ownerTokenAccount = getAssociatedTokenAddressSync(tokenMint, tokenOwnerPDA, true)

const userTokenAccount = getAssociatedTokenAddressSync(tokenMint, wallet.publicKey, false)

// Create instruction data buffer
const data = Buffer.alloc(18)
data.writeUint8(3, 0) // Instruction index for SellToken
data.writeUint8(pdaTokenNonce, 1) // PDA nonce
data.writeBigUInt64LE(tokenToSpend, 2) // Token amount
data.writeBigUInt64LE(minSolToReceive, 10) // Minimum SOL
data.writeUint8(logAuthorityBump, 18) // Log authority bump

const sellTokenIx = new TransactionInstruction({
  programId: SC_BONDING_CURVE_PROGRAM_ID,
  keys: [
    { pubkey: wallet.publicKey, isSigner: true, isWritable: true },
    { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
    { pubkey: tokenOwnerPDA, isSigner: false, isWritable: true },
    { pubkey: tokenMint, isSigner: false, isWritable: false },
    { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },
    { pubkey: userTokenAccount, isSigner: false, isWritable: true },
    { pubkey: FEE_ACCOUNT, isSigner: false, isWritable: true },
    { pubkey: SC_BONDING_CURVE_PROGRAM_ID, isSigner: false, isWritable: false },
    { pubkey: propertiesAccount, isSigner: false, isWritable: false },
    { pubkey: logAuthority, isSigner: false, isWritable: false },
  ],
  data: data,
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.something.cool/sc-bonding-curve/functions/sell-token.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
