> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-nft-comparison.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 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 the action phase will be interrupted and the bounce phase will be initiated;
   * if not, then in case of any failure the reservation action will be skipped.
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`](https://beta-docs.ton.org/tvm/exit-codes#34%3A-invalid-or-unsupported-action) is thrown.
* If `mode` has flag `8` but not flag `4`, then the error [`34`](https://beta-docs.ton.org/tvm/exit-codes#34%3A-invalid-or-unsupported-action) is thrown.
* If after step 3, `reserve` is negative, then the error [`34`](https://beta-docs.ton.org/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`](https://beta-docs.ton.org/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`, then in case of any of the above errors a [bounce message](/foundations/messages/internal#bounces) is sent back to a sender.
