# # Chapter 5

In this new installment of our tutorials, we are going to talk about money!
One of the main advantages of smart contracts is that they are "programmable money": they let you store, manipulate and send tez in a predictable way. Smart contracts can work as middle men and verify that a set of conditions is met before initiating a transaction, sending a certain amount of tez or doing any other modification.

In the previous tutorials, we encountered a couple of instructions that push useful information about the smart contract and its context onto the stack: you may remember `NOW` that adds the current timestamp on top of the stack. This is not the only one. Michelson provides a few instructions that give you access to a lot of information. In this chapter, we are going to focus on instructions that are related to the financial aspect of smart contracts: `BALANCE`, `AMOUNT`, `TRANFER_TOKENS`. You will also get a refresher about `mutez` operations. At the end of the chapter, you will have everything you need to know in order to handle financial operations in your smart contracts 🤑

## #`mutez` and `mutez` operations

The `mutez` (or micro-tez) type is a special type that allows you to manipulate financial values in your smart contracts. `mutez` are indivisible and always non-negative (as exposed below, a few restrictions are set to avoid negative values of `mutez`). It may seem a little strange at the beginning, but `mutez` values are NOT tez, they only represent a financial value. If you write `PUSH mutez 1000`, this doesn't mean you added 1,000 microtez out of thin air in your smart contract. You merely create a value of a certain type to easily manipulate other values.

You can use different arithmetic operations for values of type `mutez`: `ADD`, `SUB`, `MUL`, `EDIV` with a few restrictions:

• `ADD` only works with two values of type `mutez`
• `SUB` only works with two values of type `mutez` AND fails if the result of the subtraction is negative
• `MUL` only works with one value of type `mutez` and one value of type `nat`, the result is of type `mutez`
• `EDIV` only works with one value of type `mutez` and one value of type `nat`, the result is of type `option`, `None` in case of a division by zero, `(Some (pair quotient remainder))` including a pair containing the quotient on the left and the remainder on the right

In addition to these operations, it is also possible to compare two values of type `mutez`. Like any other value, this comparison yields an `int` between `-1` and `1`.

Now let's see some examples:

We initialize a simple contract to test these operations:

``````storage mutez ;
parameter unit ;
BEGIN Unit 1000 ;
``````
```stdoutstorage mutez;
parameter unit;
BEGIN: use %default; drop all; push (Unit, 1000);```
value type
`Pair Unit 1000`
`pair unit mutez`

Now let's separate the storage and push a new value of type `mutez` (nothing new here):

``````CDR @storage ;
PUSH mutez 2000 ;
DUMP ;
``````
```stdoutCDR: pop (Unit, 1000); push 1000;
PUSH: push 2000;```
value type name
`2000`
`mutez`
`1000`
`mutez`
`@storage`

With the `ADD` instruction, we can remove the two values of type `mutez` from the stack, add them together and push the result back to the stack:

``````ADD ;
``````
value type
`3000`
`mutez`

After adding values together, let's try to subtract one from another! We push a new value of type `mutez` and use the one already present in the stack to demonstrate `SUB`:

``````PUSH mutez 500 ;
SWAP ;
SUB ;
``````
```stdoutPUSH: push 500;
SWAP: pop 500, 3000; push 500; push 3000;
SUB: pop 3000, 500; push 2500;```
value type
`2500`
`mutez`

Did you notice the `SWAP` instruction? You must make sure that the two elements are in the right order. If you try `mutez 500 - mutez 3000`, the contract will fail because `mutez` values cannot be negative.

Next, we can multiply `mutez` values with `nat` values (to ensure positive results). In this situation, the order of the values doesn't matter, so no need to swap them:

``````PUSH nat 4 ;
MUL ;
``````
```stdoutPUSH: push 4;
MUL: pop 4, 2500; push 10000;```
value type
`10000`
`mutez`

As you can see, the value returned by `MUL` is also of type `mutez`.

As it was the case for the other numeric values, using `EDIV` with `mutez` is also a bit more complex. If you remember from the previous chapter, the result of `EDIV` is an option. If you try a division by zero, the option will have the value `None`. Otherwise, it has a value of type `pair` that contains the quotient on the left and the remainder on the right.

We can write a small piece of code that tries to divide the value on top of the stack by the value we've just pushed. If this value is `0`, the contract fails. Otherwise, it extracts the quotient and the remainder and rearrange them in this order in the stack:

``````PUSH nat 10 ;
SWAP ;
EDIV ;
IF_NONE
{ PUSH string "DivisionByZero" ; FAILWITH }
{
DUP ;
CAR @quotient ;
SWAP ;
CDR @remainder ;
SWAP ;
} ;
DUMP ;
``````
```stdoutPUSH: push 10;
SWAP: pop 10, 10000; push 10; push 10000;
EDIV: pop 10000, 10; push ((1000, 0),);
IF_NONE: pop ((1000, 0),); push (1000, 0);
DUP: push (1000, 0);
CAR: pop (1000, 0); push 1000;
SWAP: pop 1000, (1000, 0); push 1000; push (1000, 0);
CDR: pop (1000, 0); push 0;
SWAP: pop 0, 1000; push 0; push 1000;```
value type name
`1000`
`mutez`
`@quotient`
`0`
`mutez`
`@remainder`

The two values we get on the stack are exactly the expected ones: `10000 / 10 = 1000` with a remainder of `0`.

Lastly, we can compare two values of type `mutez` and check if one is equal, greater or less than the other one. This will be particularly useful when you want to verify that users send the correct amount of tez required by your contract:

``````PUSH mutez 500 ;
COMPARE ;
EQ ;
``````
```stdoutPUSH: push 500;
COMPARE: pop 500, 1000; push -1;
EQ: pop -1; push False;```
value type
`False`
`bool`

We're adding here an extra step to check if the newly added value in the stack is equal to the one already present. As they are not equal, `False` is pushed onto the stack. Obviously, you can use any of the instructions we studied in Chapter three outside of `EQ`.

## #`BALANCE`, `AMOUNT` and `NOW`

Michelson provides a few instructions that are very useful to check the context of execution.

Every time a smart contract runs, a few "variables" are available about data related to the current execution. For example, every transaction sent to a smart contract has an amount of tez attached to it (even if this is amount may be `0`). You may want to have access to this amount, for example, to check if the users sent enough tez for the service they requested or to update their token balance.
You can easily add this piece of information to the stack by using `AMOUNT`. The `AMOUNT` instruction will simply push a new element on top of the stack of type `mutez` whose value is equal to the amount sent along the transaction.

Here are two examples to showcase what you can do with the `AMOUNT` instruction:

``````storage mutez ;
parameter unit ;
code {
CDR ;
AMOUNT ;
IFCMPGT
{ AMOUNT ; NIL operation ; PAIR }
{ FAIL }
} ;

RUN %default Unit 100 ;
``````
```stdoutstorage mutez;
parameter unit;
code { CDR ; AMOUNT ; { { COMPARE ; GT } ; IF { AMOUNT ; NIL operation ; PAIR } { { UNIT ; FAILWITH } } } };
RUN: use %default; drop all; push (Unit, 100);
CDR: pop (Unit, 100); push 100;
AMOUNT: push 0;
COMPARE: pop 0, 100; push -1;
GT: pop -1; push False;
IF: pop False;
UNIT: push Unit;
FAILWITH: pop Unit;```
```stderrMichelsonRuntimeError: Unit
at RUN -> IF -> FAILWITH```

The contract fails as expected. Indeed, there is no tez attached to this transaction, so the value contained in `AMOUNT` is not greater than the one in the storage.
Because this environment is detached from the blockchain, you have to specify yourself the value you want to give to `amount` and use a non-Michelson instruction that works only in the context of these notebooks: `PATCH`. Here is how it works:

``````storage mutez ;
parameter unit ;
code {
PATCH AMOUNT 200 ;
CDR ;
AMOUNT ;
IFCMPGT
{ AMOUNT ; NIL operation ; PAIR }
{ FAIL }
} ;

RUN %default Unit 100 ;
``````
```stdoutstorage mutez;
parameter unit;
code { PATCH AMOUNT 200 ; CDR ; AMOUNT ; { { COMPARE ; GT } ; IF { AMOUNT ; NIL operation ; PAIR } { { UNIT ; FAILWITH } } } };
RUN: use %default; drop all; push (Unit, 100);
PATCH: set AMOUNT=200;
CDR: pop (Unit, 100); push 100;
AMOUNT: push 200;
COMPARE: pop 200, 100; push 1;
GT: pop 1; push True;
IF: pop True;
AMOUNT: push 200;
NIL: push [];
PAIR: pop [], 200; push ([], 200);```
value type
`200`
`mutez`

You can see that the newly returned storage is `mutez 200` as expected, because `200` is greater than `100`.

Other scenario: you create a smart contract and you want to prevent people from sending any tez. To do so, you must check if the amount is equal to `0` before proceeding and if it is not the case, the contract fails:

``````storage string ;
parameter unit ;
code {
PATCH AMOUNT ;
DROP ;
AMOUNT ;
PUSH mutez 0 ;
IFCMPNEQ
{ FAIL }
{
PUSH string "No amount!" ;
NIL operation ;
PAIR
}
} ;

RUN %default Unit "" ;
``````
```stdoutstorage string;
parameter unit;
code { PATCH AMOUNT ; DROP ; AMOUNT ; PUSH mutez 0 ; { { COMPARE ; NEQ } ; IF { { UNIT ; FAILWITH } } { PUSH string "No amount!" ; NIL operation ; PAIR } } };
RUN: use %default; drop all; push (Unit, '');
PATCH: unset AMOUNT;
DROP: pop (Unit, '');
AMOUNT: push 0;
PUSH: push 0;
COMPARE: pop 0, 0; push 0;
NEQ: pop 0; push False;
IF: pop False;
PUSH: push No amount!;
NIL: push [];
PAIR: pop [], No amount!; push ([], 'No amount!');```
value type
`"No amount!"`
`string`

You can also use `PATCH AMOUNT` with no value, which will be `0` by default. We then use the `IFCMPNEQ` instruction to check if the value on top of the stack (the `0` we pushed just before) is not equal to the one below (the amount). Be careful to push a value of type `mutez` for the comparison.
If the result of the comparison is true (i.e the amount is not equal to `0`), the contract fails. Otherwise, we pushed the amount again (remember that every instruction starting with `IF` removes the value(s) on top of the stack) and end the execution by saving the amount in the storage.

In some cases, you would like to know the current balance of the contract before running a piece of code. For example, one of your users requests to withdraw his/her share in the smart contract and you need to make sure there are enough funds before initiating the transaction. You may also want to block incoming transactions if the balance of the contract reaches a certain limit.

In these cases, you can use `BALANCE`. Just like `AMOUNT`, `BALANCE` is an instruction that pushes a new value on top of the stack containing the current balance of the smart contract in `mutez`.

Let's write a smart contract that keeps track in the storage of the last transaction sent after making sure the current balance doesn't exceed a certain limit:

``````storage mutez ;
parameter unit ;
code {
DROP ;
PATCH AMOUNT 10000000 ; ## manual setting of amount
PATCH BALANCE 25700000 ; ## manual setting of balance
AMOUNT ;
BALANCE ;
DUP ;
PUSH mutez 100000000 ; # 100 tez
IFCMPGT
{ NIL operation ; PAIR }
{ PUSH string "BalanceExceeded" ; FAILWITH }
} ;

RUN %default Unit 1000 ;
``````
```stdoutstorage mutez;
parameter unit;
code { DROP ; PATCH AMOUNT 10000000 ; PATCH BALANCE 25700000 ; AMOUNT ; BALANCE ; ADD ; DUP ; PUSH mutez 100000000 ; { { COMPARE ; GT } ; IF { NIL operation ; PAIR } { PUSH string "BalanceExceeded" ; FAILWITH } } };
RUN: use %default; drop all; push (Unit, 1000);
DROP: pop (Unit, 1000);
PATCH: set AMOUNT=10000000;
PATCH: set BALANCE=25700000;
AMOUNT: push 10000000;
BALANCE: push 25700000;
ADD: pop 25700000, 10000000; push 35700000;
DUP: push 35700000;
PUSH: push 100000000;
COMPARE: pop 100000000, 35700000; push 1;
GT: pop 1; push True;
IF: pop True;
NIL: push [];
PAIR: pop [], 35700000; push ([], 35700000);```
value type
`35700000`
`mutez`

This is a very simple smart contract that does one simple thing: it adds the incoming amount to the balance, compares the result with the limit we manually introduce (with `PUSH mutez 100000000 ;`), if the limit is greater than the addition of the amount and the balance, everything is fine, we save the amount in the storage and end the execution. However, if the limit is exceeded, we throw an error with the `FAIL` instruction.

If you try to change the values (for example adding a `0` to the balance), you can make the contract fail to test that it works properly.

We already introduced `NOW` in the previous chapters. The instruction pushes the current timestamp onto the stack. This is a very useful feature for time-related actions: for example, we can make a smart contract fail if a transaction comes before a certain period ended since the last transaction:

``````storage timestamp ;
parameter unit ;
code {
CDR ;
PUSH int 3600 ; ## 60 sec * 60 min = 1 hour interval
PATCH NOW 1592381823 ;
NOW ;
IFCMPGE
{ NOW ; NIL operation ; PAIR }
{ PUSH string "InvalidInterval" ; FAILWITH }
} ;

RUN %default Unit 1592379223 ;
``````
```stdoutstorage timestamp;
parameter unit;
code { CDR ; PUSH int 3600 ; ADD ; NOW ; { { COMPARE ; GE } ; IF { NOW ; NIL operation ; PAIR } { PUSH string "InvalidInterval" ; FAILWITH } } };
RUN: use %default; drop all; push (Unit, 1592379223);
CDR: pop (Unit, 1592379223); push 1592379223;
PUSH: push 3600;
ADD: pop 3600, 1592379223; push 1592382823;
NOW: push 1592456946;
COMPARE: pop 1592456946, 1592382823; push 1;
GE: pop 1; push True;
IF: pop True;
NOW: push 1592456946;
NIL: push [];
PAIR: pop [], 1592456946; push ([], 1592456946);```
value type
`1592456946`
`timestamp`

As you can see, the contract stores the timestamp of the last successful execution. When a transaction comes, it adds 3,600 seconds to that timestamp and compares it to the current timestamp. If one hour has passed, the new timestamp is saved into the storage. Otherwise, an error is raised and the contract fails.

In the contract, we use `PATCH NOW 1592381823` in order to force a certain value for our `NOW` instruction and see the contract fail. If you comment out this line (just add `##` at the very beginning of the line) and run the contract again, you can see that it passes now, because there is more than one hour between `NOW` and the timestamp in the storage. The value returned by `NOW` is then saved into the storage.

## # Address, contract and token transfer

One of the many features of smart contracts is their ability to transfer money. You can send tez to a smart contract, you can send them from the smart contract to an address and you can even exchange tez between smart contracts! You can let anyone transfer money in and out but you can also enforce certain rules that dictate who can make transfers and how these transfers can happen. After reading this section, you will know everything you need to manage tez in your smart contracts!

Let's start from the beginning, with the `address` type. `address` is a type in Michelson reserved for addresses. It can be used both for implicit account (starting with tz1, tz2 or tz3) and smart contract (starting with KT1) addresses. You can type an address as a string when you want, for example, to add it onto the stack:

``````storage address ;
parameter unit ;
code {
DROP ;
NIL operation ;
PAIR
} ;

RUN %default Unit "" ;
``````
```stdoutstorage address;
parameter unit;
code { DROP ; PUSH address "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" ; NIL operation ; PAIR };
RUN: use %default; drop all; push (Unit, '');
DROP: pop (Unit, '');
PUSH: push tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb;
NIL: push [];
PAIR: pop [], tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb; push ([], 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb');```
value type
`"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb"`
`address`

Be aware that the `address` type does not ensure that the address is a valid address, only that the string follows the address format.

If you want to ensure that the address is valid, you can use the `contract (param)` type. This type guarantees that the address is a valid, existing account with a parameter of type `param`. In case of an implicit account, `param` is equal to `unit`. It is impossible to "push" a value of type `contract` onto the stack but you can receive it as a parameter, you can get it with the `IMPLICIT_ACCOUNT` and `SELF` instructions or you have to start with a value of type `address` and cast it to a value of type `contract`. Let's see an example before detailing what happens:

``````storage (contract unit) ;
parameter unit ;
code {
DROP ;
CONTRACT unit ;
IF_NONE
{ FAIL }
{ NIL operation ; PAIR }
} ;

RUN %default Unit "" ;
``````
```stdoutstorage (contract unit);
parameter unit;
code { DROP ; PUSH address "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" ; CONTRACT unit ; IF_NONE { { UNIT ; FAILWITH } } { NIL operation ; PAIR } };
RUN: use %default; drop all; push (Unit, '');
DROP: pop (Unit, '');
PUSH: push tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb;
CONTRACT: pop tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb; skip check; push ('tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default',);
IF_NONE: pop ('tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default',); push tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default;
NIL: push [];
PAIR: pop [], tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default; push ([], 'tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default');```
value type
`"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default"`
`contract unit`

In this example, we convert a value of type `address` to a value of type `contract` and save the result in the storage. Several steps are necessary to achieve it:

1. We remove the first element of the stack with `DROP`.
2. We add the address on top of the stack with `PUSH`.
3. We use a special instruction called `CONTRACT` to cast the address to a contract value. Note that we provide a parameter of type `unit` indicating that the resulting value will be an implicit account.

NOTE

smart contracts can also have a parameter of type `unit`, this kind of parameter doesn't necessarily confirm that you are dealing with an implicit account.

1. Two things may happen at this point: if the address is invalid or doesn't exist, `CONTRACT` returns the value `None` of type option. We can use it to make the contract fail. If the address is valid and exists, `CONTRACT` returns the value `(Some (contract param))` of type option that we unwrap in the second branch of the conditional structure to get the value of type `(contract unit)`. This value is then saved in the storage.

NOTE

In the Jupyter notebooks, the `Contract` values are not typechecked, so they always return `(Some value)`. Be careful when you use your code in a compiler as it can be a source of error.

In a real-life scenario, you wouldn't probably go through all these steps just to save the result in the storage. This operation can be particularly useful when you want to send tokens from a contract. Michelson provides an instruction that allows you to withdraw tez from the contract balance and send them to an implicit account or another contract: `TRANSFER_TOKENS`. The use of this instruction is not difficult by itself but you have to make sure to get its necessary parameters in the right order in the stack before calling it. Let's see an example first to observe what `TRANSFER_TOKENS` does:

``````storage unit ;
parameter unit ;
BEGIN Unit Unit ;
PATCH BALANCE 10000000 ;
DROP ;
``````
```stdoutstorage unit;
parameter unit;
BEGIN: use %default; drop all; push (Unit, Unit);
PATCH: set BALANCE=10000000;
DROP: pop (Unit, Unit);```

This initializes the storage and the parameter before dropping the first element of the stack. We also add 10 tez to the balance so we have something to send to the receiver's address.

``````PUSH address "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" ;
CONTRACT unit ;
DUMP ;
``````
```stdoutPUSH: push tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb;
CONTRACT: pop tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb; skip check; push ('tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default',);```
value type
`Some "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default"`
`option (contract unit)`

Like in the previous contract, we push the receiver's address to the stack and convert it to a `(contract unit)` type.

``````IF_NONE
{ PUSH string "InvalidAddress" ; FAILWITH }
{ } ;
DUMP ;
``````
value type
`"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default"`
`contract unit`

`IF_NONE` verifies that the `CONTRACT` instruction succeeded and that a value has been returned. In this case, the value is the address where we will send the tez, of type `(contract unit)`.

``````PUSH mutez 5000000 ;
DUMP ;
``````
value type
`5000000`
`mutez`
`"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default"`
`contract unit`

We then push the amount we want to send to the receiver's address.

``````PUSH unit Unit ;
DUMP ;
``````
value type
`Unit`
`unit`
`5000000`
`mutez`
`"tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb%default"`
`contract unit`

Because we are sending an amount to an implicit account, the expected parameter of the value of type `(contract unit)` is `unit`, so we just need to provide an element of type `unit` to the `TRANFER_TOKENS` instruction.
Note that the three parameters necessary to transfer tokens are now on top of the stack and in the right order:

1. The parameter expected for the address (`unit` for implicit accounts)
2. The amount to be sent in `mutez`
3. The receiver's address converted to a value of type `(contract param)`
``````TRANSFER_TOKENS ;
DUMP ;
``````
value type
```amount: '5000000'
entrypoint: default
kind: transaction
parameters: Unit
target: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb```
`operation`

Calling the `TRANSFER_TOKENS` instruction forges a new operation. Remember that contract executions in Michelson are self-contained: they do not communicate with the outside. The execution goes from its beginning to its end and only then it is possible to send new transactions.
You can see that the value we now have on top of the stack is of type `operation` and contains all the information we previously added to the stack: the amount to be sent, the entrypoint to call (`default` by default or in case of a transaction to an implicit account), the operation kind, the parameters (`unit` for transactions to implicit accounts) and the target address. The only thing left now is to add this operation to the list of operations returned at the end of the contract.

``````NIL operation ;
SWAP ;
CONS ;
DUMP ;
``````
```stdoutNIL: push [];
SWAP: pop [], <send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>; push []; push <send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>;
CONS: pop <send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>, []; push ['<send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>'];```
value type
```- amount: '5000000'
entrypoint: default
kind: transaction
parameters: Unit
target: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb```
`list operation`

Are you excited about finally using that list of operations we have been returning empty so far? 😅

In order to include the operation into the list of operations, you add an empty list as usual with `NIL operation`, you use `SWAP` because the element to add to the list must be just above in the stack and you call the `CONS` instruction which prepends the value to the list. Now you can return the pair with the list of operations and the storage:

``````UNIT ;
SWAP ;
PAIR ;
COMMIT ;
``````
```stdoutUNIT: push Unit;
SWAP: pop Unit, ['<send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>']; push Unit; push ['<send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>'];
PAIR: pop ['<send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>'], Unit; push (['<send 5000000 to tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb>'], Unit);
COMMIT:```
value type
`Unit`
`unit`

kind target amount entrypoint parameters
`transaction`
`tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb`
`5000000`
`default`
`Unit`

Nothing groundbreaking here, we push a new `unit` on top of the stack, we use `SWAP` because the list of operations must be on the left of the pair and then `PAIR`.