# Noxx - EVM Deep Dives

## Part 1

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy" %}
Part 1
{% endembed %}

This article should be a review for you. It explains <mark style="color:red;">**function selector**</mark> step and step and gives an instance in EVM Playground so you can follow along:

{% embed url="https://www.evm.codes/playground?unit=Wei&callData=0x6057361d000000000000000000000000000000000000000000000000000000000000000a&codeType=Mnemonic&code=%27%210%7E0KCALLDATALOAD%7E2z2qw%21E0%7E3KSHR%7E5z2qwDUP1%7E6%28X4_2E64CEC1%7E7KEQ%7E12z5qwX2_3B%7E13%28*I%7E16z3qwDUP1%7E17KX4_6057361D%7E18KEQ%7E23z5qwX2_59%7E24K*I%7E27z3qwkY+wX30_0%7E28KwZGV59z31q%211%7E60+%7BG%7DW%7DKwkYwX26_0%7E62z2qKZstore%7Buint256V89z27q%210+ZContinueW.KK%27%7E+ZOffset+z+%7Bprevious+instruFoccupies+w%5Cnq%29s%7DwkZThes-ar-just+paddingNenabl-usNgetN_+0xZ%2F%2F+Yprogram+counter+59+%26+89XPUSHW+funFexecution...V%7D%29codew*DEST%7EN+to%28wwGretrieve%7BFction+-e+*JUMP%29+byte%28+K%21X1_%01%21%28%29*-FGKNVWXYZ_kqwz%7E_&fork=merge" %}
Function Selector
{% endembed %}

Click "Run" and then "Step into" to execute one instruction at a time:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FCTSQxeXjZxN4g9GXNtQf%2Fimage.png?alt=media&#x26;token=6bb200c1-522c-4b62-8737-54eaa2f9fb1b" alt=""><figcaption><p>EVM Playground UI</p></figcaption></figure>

## Part 2

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-d6b" %}
Part 2
{% endembed %}

This article explains <mark style="color:red;">**memory layout**</mark> and <mark style="color:red;">**free memory pointer**</mark>.

### Memory layout

Solidity memory layout, quoted from Solidity doc:

> Solidity’s memory layout reserves four 32-byte slots:
>
> * `0x00` - `0x3f` (64 bytes): scratch space
> * `0x40` - `0x5f` (32 bytes): free memory pointer
> * `0x60` - `0x7f` (32 bytes): zero slot

I made a diagram for easier memorization:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FbjlOaNYuFMSBmyaNlzuU%2Fimage.png?alt=media&#x26;token=46f429b3-a117-4202-b9ca-c4dd548294eb" alt=""><figcaption><p>memory layout</p></figcaption></figure>

### **Memory expansion**

While walking through the EVM playground above you may have noticed a few strange occurrences. First, when we wrote a single byte `0x22` using `MSTORE8` to memory location 32 (`0x20`) the memory changed from

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FABLm9qSRMz3IfrCWFh5v%2Fimage.png?alt=media&#x26;token=39f0038b-278e-48fa-95c5-fa68032abc27" alt=""><figcaption><p>before</p></figcaption></figure>

to

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FpWCYQpnvJKxtxXRCDfQj%2Fimage.png?alt=media&#x26;token=d0703a3a-d68f-46d6-8fda-b33c0b6f0f2d" alt=""><figcaption><p>after</p></figcaption></figure>

You may ask the question, what’s with all the additional zeros we only added 1 byte?

When your contract writes to memory, you have to pay for the number of bytes written. If you are writing to an area of memory that hasn't been written to before, there is an additional memory expansion cost for using it for the first time.

Memory is expanded in 32 bytes (256-bit) increments when writing to previously untouched memory space.

> Memory expansion costs scale linearly for the first 724 bytes and quadratically after that.

Above our memory was 32 bytes before we wrote 1 byte at location 32. At this point we began writing into untouched memory, as a result, the memory was expanded by another 32-byte increment to 64 bytes.

Note that all locations in memory are well-defined initially as zero which is why we see `2200000000000000000000000000000000000000000000000000000000000000` added to our memory.

## Part 3

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-3ea" %}
Part 3
{% endembed %}

This part covers <mark style="color:red;">**storage**</mark>.

### Data Structure

Contract storage is abstracted as a 32-byte to 32-byte mapping. That means there is $$2^{256}$$storage slots and each slot is a 256-bit wide chunk. The number of slots is a huge number, therefore if the slot contains 0 then it is not stored by the nodes of the network. This is why setting a state variable back to 0 would grant you gas refund.

Diagram of storage:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FsWfMYo41zqmZIFvE6tmb%2Fimage.png?alt=media&#x26;token=b7f5dc6c-0d85-49d6-b54f-76060e04afbd" alt=""><figcaption><p>storage</p></figcaption></figure>

Contract variables that are declared as storage variables can be split into 2 camps <mark style="color:red;">**fixed-size**</mark> and <mark style="color:red;">**dynamic-size**</mark>.

If you have worked through Ethernaut, fixed-size variables storage layout should be a piece of cake -> slot packing.

To learn more about dynamic size variables refer to the [“Program the Blockchain”](https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/) [post](https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/).

### EVM Storage Opcodes

#### SSTORE

We’ll start with SSTORE it takes in a 32-byte key and a 32-byte value from the call stack and stores that 32-byte value at that 32-byte key location. Check out [this](https://www.evm.codes/playground?unit=Wei\&codeType=Mnemonic\&code=%27z1uFFv1%200w~z2uy8965w%27~%5Cnz%2F%2F%20Example%20yv2%20w~SSTORE~v~PUSHuy0xFF%01uvwyz~_) EVM playground to see how it works.

#### SLOAD

Next, we have SLOAD which takes in a 32-byte key from the call stack and pushes the 32-byte value stored at that 32-byte key location onto the call stack. Check out [this](https://www.evm.codes/playground?unit=Wei\&codeType=Mnemonic\&code=%27wSet%20up%20thrstatez46z0~SSTOREy1z0vy2z1v~%27~%5Cnz~PUSH1%20y~~wExamplrw%2F%2F%20v~SLOADre%20%01rvwyz~_) EVM playground to see how it works.

The question you should be asking yourself at this stage is if SSTORE and SLOAD only deal in 32-byte values how can you extract a variable that has been packed into a 32-byte slot. We will be answering this question soon.

### Storing & Retrieving Packed Variables

{% hint style="warning" %}
This part is pretty diffcult to follow. Focus, focus, focus.
{% endhint %}

Sample code:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FgB5ZHpCc4lIzaeJkDAgP%2Fimage.png?alt=media&#x26;token=c7c1e500-a33c-4a52-9e34-f20bfee4b5fc" alt=""><figcaption><p>Storing &#x26; Retrieving Packed Variables</p></figcaption></figure>

Remember that hexadecimal numbers are ultimately seen as binary numbers by the machine. This is important as a number of <mark style="color:red;">**bitwise operations**</mark> are used in slot packing:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FlV4dLBmUI6NNfWt6Y8AN%2Fimage.png?alt=media&#x26;token=7a75ed4c-e316-4b28-9db8-e8f8855d027c" alt=""><figcaption><p>hex to binary</p></figcaption></figure>

Next noxx covered AND, OR, NOT. You should be very familiar with these.

Storing `value1 = 1` is trivial. Let's focus on `value2 = 22`. The logic for `value3` and `value4` is the same as `value2`.

The computation will be using the following values:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FVxOOsBcDwJgrxv9aQE6d%2Fimage.png?alt=media&#x26;token=5590802e-82b4-4c5c-b31b-b1fcdf61b651" alt=""><figcaption><p>values</p></figcaption></figure>

The first thing the EVM does is use the <mark style="color:red;">**EXP**</mark> opcode which takes in a base integer and an exponent and returns the value. Here we use `0x0100` as the base integer which represents a 1-byte offset and raise it to exponent `0x04` which is the start position for `value2`. The image below shows why the returned value is useful:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FxEjJOtiURB5NOsRbAluu%2Fimage.png?alt=media&#x26;token=70231375-a03f-4883-9e31-aea899e3a418" alt=""><figcaption><p>value2 storage position computation</p></figcaption></figure>

We can’t use this value however as it would overwrite `value1` which has already been stored. This is where bitmasks are utilized:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2F9dNZjXVNJGXqtKMQRXai%2Fimage.png?alt=media&#x26;token=3fa9e690-ffc4-4651-b810-752d2ea040aa" alt=""><figcaption><p>bitmask</p></figcaption></figure>

Here’s another example to crystalise what is happening. This is the same process but looking at what would happen if all 4 values had already been stored and we wanted to update value2 from 22 to 99. Look out for the existing `0x016` value being zeroed out:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FTOkh8GkFlddH5SqsqBpd%2Fimage.png?alt=media&#x26;token=18f930b7-1757-453f-b687-b99153fc07de" alt=""><figcaption><p>another example</p></figcaption></figure>

<mark style="color:red;">**Bitwise OR**</mark> can combine the values we have:

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2F4JuwWeFzRGxYzoVc3m5n%2Fimage.png?alt=media&#x26;token=be9f445c-2897-429c-a7b2-6650e24d521e" alt=""><figcaption><p>Bitwise OR</p></figcaption></figure>

## Part 4

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-5a5" %}
Part 4
{% endembed %}







## Part 5

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-a5f" %}
Part 5
{% endembed %}







## Part 6

{% embed url="https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-16e" %}
Part 6
{% endembed %}







