> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/foundations/actions/reserve",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Reserve coins

*Reserving coins* is one of the actions that a smart contract can perform during the [action phase](/foundations/phases#action-phase). In TVM it is implemented via the [`RAWRESERVE`](/tvm/instructions#fb02-rawreserve) instruction that takes from the stack an `amount` of Toncoin (in nanotoncoins) to reserve and an integer `mode` specifying a way of the reservation. The reservation action is queued to the *output action list* of a smart contract, which contains other actions such as *message sends*.

The `RAWRESERVE` instruction is equivalent to creating an outbound message carrying the specified `amount` of nanotoncoin to oneself. But unlike regular sending of a message, the reservation action does not create a new message and does not incur any forward fees. Its primary goal is to limit the amount of Toncoin that can be spent by subsequent actions.

## Modes

The `mode` parameter is a bitmask that specifies how a reserved amount is calculated. The resulting mode value can have the following base modes:

| Mode value | Convenient name    | Description                                             |
| :--------: | ------------------ | ------------------------------------------------------- |
|     `0`    | `ReserveExact`     | Reserves exactly the specified `amount` of nanotoncoin. |
|     `1`    | `ReserveAllExcept` | Reserves all but the specified `amount` of nanotoncoin. |
|     `2`    | `ReserveAtMost`    | Reserves at most the specified `amount` of nanotoncoin. |

Additionally, the resulting `mode` can have the following optional flags added:

| Flag value | Convenient name             | Description                                                                                                                           |
| :--------: | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|    `+4`    | `ReserveAddOriginalBalance` | Increases the `amount` by the original balance (i.e. without incoming message value) of the current account before the compute phase. |
|    `+8`    | `ReserveInvertSign`         | Negates the `amount` value before performing the reservation.                                                                         |
|    `+16`   | `ReserveBounceIfActionFail` | Bounces the transaction if the reservation fails.                                                                                     |

## Behavior

Notation:

* `amount` – the amount of Toncoin passed to the `RAWRESERVE` instruction.
* `mode` – the integer mode passed to the `RAWRESERVE` instruction.
* `original_balance`:
  * if after the storage phase, account's balance is less than the value of incoming message with bounce flag set to `false`, then `original_balance` is set to 0;
  * otherwise, `original_balance` equals account's balance before the compute phase minus incoming message value.
* `remaining_balance` – account's balance before the reservation action.
* `reserve` – the final amount to be reserved.

The algorithm is as follows:

1. Check that `mode` has flag `ReserveBounceIfActionFail`:
   * if so, then in case of any failure during reservation, the [bounce phase](/foundations/phases#bounce-phase) is initiated.
2. Set `reserve` to `amount`.
3. Check that `mode` has flag `ReserveAddOriginalBalance`:
   1. If so, then check that `mode` has flag `ReserveInvertSign`:
      * if so, then set `reserve` to `original_balance - reserve`;
      * otherwise, increase `reserve` by `original_balance`.
   2. Otherwise, if `mode` has flag `ReserveInvertSign`, throw the error "invalid reserve mode".
4. Check that `mode` has flag `ReserveAtMost`:
   * if so, then set `reserve` to `min(reserve, remaining_balance)`.
5. Check that `mode` has flag `ReserveAllExcept`:
   * if so, then set `reserve` to `remaining_balance - reserve`.
6. Set `remaining_balance` to `remaining_balance - reserve`.

If there were no errors, then the reservation action was successful, and the subsequent actions can spend only at most the new `remaining_balance`.

For example, suppose that:

* `amount` = `0.1` TON;
* `mode` = `1 + 4 + 8` (`ReserveAllExcept`, `ReserveAddOriginalBalance`, `ReserveInvertSign`);
* `original_balance` = `2` TON;
* `remaining_balance` = `3` TON.

Then the reservation proceeds as follows:

1. `mode` has flag `ReserveBounceIfActionFail`? No.
2. `reserve` = `0.1` TON.
3. `mode` has flag `ReserveAddOriginalBalance`? Yes.
   * `mode` has flag `ReserveInvertSign`? Yes.
   * Thus, `reserve` = `original_balance - reserve` = `2 - 0.1` = `1.9` TON.
4. `mode` has flag `ReserveAtMost`? No.
5. `mode` has flag `ReserveAllExcept`? Yes.
   * Thus, `reserve` = `remaining_balance - reserve` = `3 - 1.9` = `1.1` TON.
6. `remaining_balance` = `remaining_balance - reserve` = `3 - 1.1` = `1.9` TON.

## Errors

The following errors can occur during the reservation flow:

* If the `mode` bitmask has more than first five ones positive bits, then the error [`34`](/tvm/exit-codes#34%3A-invalid-or-unsupported-action) is thrown.
* If `mode` has flag `8` but not flag `4`, then the error [`34`](/tvm/exit-codes#34%3A-invalid-or-unsupported-action) is thrown.
* If after step 3, `reserve` is negative, then the error [`34`](/tvm/exit-codes#34%3A-invalid-or-unsupported-action) is thrown.
* Passing a negative `amount` also results in the same error.
* If after step 4, `reserve` is greater than `remaining_balance`, then the error [`37`](/tvm/exit-codes#37%3A-not-enough-toncoin) ("Not enough Toncoin") is thrown.
* Some problems with unpacking the reserve action cell.
* A problem related to extra-currency.

If the action had flag `16`, i.e., `ReserveBounceIfActionFail`, then in case of any of the above errors the transaction enters the [bounce phase](/foundations/phases#bounce-phase).
