# Buying and selling

## Buying

A buy is a direct call to the **bonding curve contract** with op `BUY_TOKENS` (`0x42555900` = `BUY\0`).

### What gets sent

| Field     | Value                                      |
| --------- | ------------------------------------------ |
| **To**    | The token's curve address                  |
| **Value** | `tonAmount + 0.2 TON`                      |
| **Body**  | `BUY_TOKENS` op + queryId + `minTokensOut` |

The contract reserves `0.15 TON` from the message value for gas. So a buy of `X TON` results in an *effective gross* of `X + 0.05 TON` hitting the curve math (and `minTokensOut` is computed against that).

### Slippage

The widget defaults to 5% slippage. The `minTokensOut` field tells the contract: "abort and refund my TON if the swap would give me fewer jettons than this". Larger trades or faster-moving curves benefit from a higher slippage tolerance.

## Selling

This is the tricky bit. **A sell is&#x20;*****not*****&#x20;a call to the curve.** It's a TEP-74 `JETTON_TRANSFER` to *your own jetton wallet*, with a `forward_payload` that tells the curve "this is a sell".

### What gets sent

| Field                  | Value                                                                                |
| ---------------------- | ------------------------------------------------------------------------------------ |
| **To**                 | **Your jetton wallet** for this token (the address `getJettonWalletAddress` returns) |
| **Value**              | `0.3 TON` (covers gas across the 3-wallet hop)                                       |
| **Body**               | Standard `JETTON_TRANSFER` (op `0x0f8a7ea5`) with:                                   |
| `destination`          | the curve address                                                                    |
| `response_destination` | your wallet (to receive excess gas)                                                  |
| `forward_ton_amount`   | `0.1 TON` (passed to the curve as msg.value)                                         |
| `forward_payload`      | `SELL` op + `minTonOut` *inline as a slice*                                          |

{% hint style="warning" %}
**Critical wire-format detail (for integrators)**

Tonton's wallet and curve are generated by **Tact**, and the field they use for `forward_payload` is typed as `Slice as remaining` — which means:

> **No `Either Cell ^Cell` tag bit before the payload.**

If you build a TEP-74-strict body with `storeBit(false)` (the standard "inline" Either-tag), the curve reads the `SELL` op shifted by 1 bit and refunds your jettons. The SDK's `buildSellTransfer()` already gets this right — *do not* re-add the Either-tag bit if you fork or rewrite the codec.
{% endhint %}

### The 0.1 TON forward limit

The curve checks the value of the `JETTON_TRANSFER_NOTIFY` it receives. If that value exceeds `~0.1 TON`, the curve refunds the sell as a safety measure. The SDK sends exactly `0.1 TON` of forward\_ton — don't bump this.

### Refund path (`jettonsIn > tokensSold`)

The curve also refunds if you try to sell more jettons than the curve has issued in total (`tokensSold`). This protects against selling "orphan" jettons — tokens that exist in a wallet but aren't backed by curve reserves (e.g., you transferred someone tokens, then they drained the curve, so the curve no longer has TON to pay back the transferred jettons).

The frontend pre-checks `sellAmount <= tokensSold` before signing and refuses to submit if it would overshoot, telling you the max sellable amount.

## Gas costs

| Action    | Wallet sends | Curve receives                         | Typical net gas burned      |
| --------- | ------------ | -------------------------------------- | --------------------------- |
| Buy 1 TON | 1.2 TON      | 1.05 TON (after wallet's 0.15 reserve) | \~0.04 TON                  |
| Sell      | 0.3 TON      | 0.1 TON forward to curve               | \~0.05 TON                  |
| Launch    | 0.5 TON      | factory + new curve init               | \~0.07 TON, no protocol fee |


---

# 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.tonton.fun/buying-and-selling.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.
