erhant 0.1.9

My personal blog, hosted on docs.rs
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
<!--
date: "2023-01-24"
tags: [ethereum, puzzles]
title: "EVM Puzzles"
summary: "Walkthrough solutions for learning EVM bytecode through puzzles."
-->

# EVM Puzzles

[EVM Puzzles](https://github.com/fvictorio/evm-puzzles/) are a collection of puzzles by [Franco Victorio](https://github.com/fvictorio). In this Markdown file, I wrote down the walkthrough for each of them.

It is crucial to understand the storage structure of EVM, I refer to [this article](https://coinyuppie.com/in-depth-understanding-of-evm-storage-mechanism-and-security-issues/) as a good resource on this. Most importantly, you should be familiar on how the stack works, and how EVM instructions use it. See the original documentation about EVM at <https://ethereum.org/en/developers/docs/evm/>.

Whenever you see a new instruction, you should immediately go and see what it is and what it does. I have used <https://www.evm.codes/> and <https://www.ethervm.io/> as my resources. For more information about EVM, you can also see their pages: <https://www.evm.codes/about> and <https://www.ethervm.io/#overview>.

Throughout this walkthrough all numbers that start with `0x` are hexadecimal, and all that do not are decimal. Furthermore, bytecodes are given in hexadecimal, and two hexadecimals are equal to a byte, as 4 bits x 2 = 8 bits = 1 byte.

In all puzzles, the objective is to have the code `STOP`, rather than `REVERT`. You basically have to get to the end!

One final remark: **please try to solve each of these before looking at the solution**! This is a great way to learn about EVM, and solving these is a rewarding feeling. Once you learn an instruction on your own, the rest will be easier; it is the first steps that is hard to take at such a low-level context. Good luck!

## Puzzle 1

```js
00      0x34      CALLVALUE
01      0x56      JUMP
02      0xFD      REVERT
03      0xFD      REVERT
04      0xFD      REVERT
05      0xFD      REVERT
06      0xFD      REVERT
07      0xFD      REVERT
08      0x5B      JUMPDEST
09      0x00      STOP
```

`JUMP` jumps to the destination specified by the top value in the stack. `CALLVALUE` pushes the call value to the stack. Looking at the code, there is a `JUMPDEST` at 8, so our call value must be 8.

## Puzzle 2

```js
00      0x34      CALLVALUE
01      0x38      CODESIZE
02      0x03      SUB
03      0x56      JUMP
04      0xFD      REVERT
05      0xFD      REVERT
06      0x5B      JUMPDEST
07      0x00      STOP
08      0xFD      REVERT
09      0xFD      REVERT
```

Here is a new instruction: [`CODESIZE`](https://www.evm.codes/#38). It pushes the size of code to the stack. Which code? Well, it is the puzzle code itself, which we can see has `10` bytes (the last line is `09` but remember that it starts from `00`).

The `SUB` instruction takes the top two values, subtracting the second one from the first. So basically, it calculates `CODESIZE - CALLVALUE`. We can see a `JUMPDEST` at `06`. So, we have the equation `CODESIZE - CALLVALUE = 10 - CALLVALUE = 6`.

Our `CALLVALUE` must be 4 Wei.

## Puzzle 3

```js
00      0x36      CALLDATASIZE
01      0x56      JUMP
02      0xFD      REVERT
03      0xFD      REVERT
04      0x5B      JUMPDEST
05      0x00      STOP
```

[`CALLDATASIZE`](https://www.evm.codes/#36) pushes the size of calldata (bytes) to the stack. There is a `JUMPDEST` at 4, so the size should be 4 bytes. Any arbitrary 4-byte calldata would suffice: `0x11223344`.

## Puzzle 4

```js
00      0x34      CALLVALUE
01      0x38      CODESIZE
02      0x18      XOR
03      0x56      JUMP
04      0xFD      REVERT
05      0xFD      REVERT
06      0xFD      REVERT
07      0xFD      REVERT
08      0xFD      REVERT
09      0xFD      REVERT
10      0x5B      JUMPDEST
11      0x00      STOP
```

`CODESIZE` is 12 and `JUMPDEST` is at 10. `XOR` is a bitwise operation that stands for exclusive-or operation. Here is its logic table:

| a   | b   | a ^ b |
| --- | --- | ----- |
| 0   | 0   | 0     |
| 0   | 1   | 1     |
| 1   | 0   | 1     |
| 1   | 1   | 0     |

Denoting `XOR` as `^` (as is the case in many programming languages) we need some value such that `CALLVALUE ^ 12 = 10`. Simple arithmethic yields `CALLVALUE = 10 ^ 12 = 6`.

## Puzzle 5

```js
00      0x34          CALLVALUE
01      0x80          DUP1
02      0x02          MUL
03      0x610100      PUSH2 0x0100
06      0x14          EQ
07      0x600C        PUSH1 0x0C
09      0x57          JUMPI
10      0xFD          REVERT
11      0xFD          REVERT
12      0x5B          JUMPDEST
13      0x00          STOP
14      0xFD          REVERT
15      0xFD          REVERT
```

Here we have a [`JUMPI`](https://www.evm.codes/#57) which is a conditional jump. `PUSH1 0x0C` above it provides the correct destination address, so all we have to care about is that the condition value be non-zero.

Looking at the lines above in order:

1. `CALLVALUE` pushes the value to the stack.
2. `DUP1` duplicates it, so there are two of the same value in the stack.
3. `MUL` multiplies these two, so we basically squared the call value.
4. `PUSH2 0x0100` pushes `0x0100` to the stack, which is `16 ^ 2` in decimals.
5. `EQ` compares the top two items in the stack, which is `16 ^ 2` and the square of our callvalue! Therefore, giving a callvalue of 16 is the winning move.

## Puzzle 6

```js
00      0x6000      PUSH1 0x00
02      0x35        CALLDATALOAD
03      0x56        JUMP
04      0xFD        REVERT
05      0xFD        REVERT
06      0xFD        REVERT
07      0xFD        REVERT
08      0xFD        REVERT
09      0xFD        REVERT
10      0x5B        JUMPDEST
11      0x00        STOP
```

[`CALLDATALOAD`](https://www.evm.codes/#35) loads a 32-byte value at the specified byte offset. If 32-bytes go beyond the length of calldata, the overflowing bytes are set to 0.

The offset to be loaded is given by the top value in the stack, which is given by `PUSH1 0x00` above. Basically, the calldata itself should have the destination address for `JUMP`. Our `JUMPDEST` is at `0x0A`, so that is our calldata!

But wait, remember that overflowing bytes are set to 0. So if we just send `0x0A`, the remaining 31 bytes will be `00` and we will have `0x0A00000000000000000000000000000000000000000000000000000000000000` which is a huge number!

Instead, we must do zero-padding to the left, and send `0x000000000000000000000000000000000000000000000000000000000000000A` as our calldata. This way, reading 32-bytes from the zero offset will yield `0x0A`.

## Puzzle 7

```js
00      0x36        CALLDATASIZE
01      0x6000      PUSH1 0x00
03      0x80        DUP1
04      0x37        CALLDATACOPY
05      0x36        CALLDATASIZE
06      0x6000      PUSH1 0x00
08      0x6000      PUSH1 0x00
10      0xF0        CREATE
11      0x3B        EXTCODESIZE
12      0x6001      PUSH1 0x01
14      0x14        EQ
15      0x6013      PUSH1 0x13
17      0x57        JUMPI
18      0xFD        REVERT
19      0x5B        JUMPDEST
20      0x00        STOP
```

The first 4 lines basically copy the entire calldata into memory. The next 4 lines create a contract, where the initialization code is taken from the memory at the position our calldata was just loaded. In other words, the first 10 lines create a contract with our calldata.

Afterwards, the next 3 lines check if the [`EXTCODESIZE`](https://www.evm.codes/#3b) is equal 1 byte. The contract that we are checking the code size is the one we just created above with `CREATE`, as `CREATE` pushes the address to the stack. `EXTCODESIZE` is the size of the runtime code of a contract, not the initialization code! The puzzle expects this to be 1 byte (lines `0C` and `0E`). So we just have to write our own initialization code to do all this.

The instruction for this is `CODECOPY`, which works similar to `CALLDATACOPY`. The initialization code will be as follows:

```js
PUSH1 0x01 // 1 byte
PUSH1 ;;;; // position in bytecode, we dont know yet
PUSH1 0x00 // write to memory position 0
CODECOPY   // copies the bytecode
PUSH1 0x01 // 1 byte
PUSH1 0x00 // read from memory position 0
RETURN     // returns the code copied above
```

In terms of bytecode, this results in `0x60 01 60 ;; 60 00 39 60 01 60 00 F3`. This is a total of 12 bytes, so the `;;;;` position will be 12, which is `0x0C`. The final bytecodes are: `0x6001600C60003960016000F3`.

This code copies 1 byte code into memory, and returns it to EVM so that contract creation is completed. The actual runtime code is arbitrary, it just has to be 1 byte. Furthermore, runtime code comes after the initialization code (starting at 12th position in this case), so we just have to append one byte to the end of the bytecodes above.

Let's add `0xEE` for no reason: `0x6001600C60003960016000F3EE`. That should do it!

## Puzzle 8

```js
00      0x36        CALLDATASIZE
01      0x6000      PUSH1 0x00
03      0x80        DUP1
04      0x37        CALLDATACOPY
05      0x36        CALLDATASIZE
06      0x6000      PUSH1 0x00
08      0x6000      PUSH1 0x00
10      0xF0        CREATE
11      0x6000      PUSH1 0x00
13      0x80        DUP1
14      0x80        DUP1
15      0x80        DUP1
16      0x80        DUP1
17      0x94        SWAP5
18      0x5A        GAS
19      0xF1        CALL
20      0x6000      PUSH1 0x00
22      0x14        EQ
23      0x601B      PUSH1 0x1B
25      0x57        JUMPI
26      0xFD        REVERT
27      0x5B        JUMPDEST
28      0x00        STOP
```

Similar to the previous puzzle, the first 4 lines copy the entire calldata into memory. The next 4 lines create a contract, the initialization code is taken from the memory at the position that calldata was just loaded.

Afterwards, 5 of `0x00` are pushed to the stack. `SWAP5` will exchange the 1st and 6th stack items, and the 6th item at that point is the address yielded from `CREATE`. Next, the remaining gas amount is pushed to stack with `GAS`. All of this was done for the sake of `CALL` instruction:

```js
CALL;
gas; // given by GAS the previous line
address; // is the address from CREATE
value; // 0
argOffset; // 0
argSize; // 0
retOffset; // 0
retSize; // 0
```

After `CALL`, a boolean result is pushed to the stack indicating its success. Looking at the following lines we see that this is expected to be 0 (`PUSH1 00` and `EQ` with `JUMPI` afterwards). So we can create a contract with a `REVERT` instruction.

```js
PUSH1 0x00
PUSH1 0x00
REVERT
```

This shall be our runtime code, which in bytecode is `0x60006000FD` at 5 bytes total. We will write the initialization code ourselves too, similar to what we did in the previous puzzle.

```js
PUSH1 0x05 // 5 bytes
PUSH1 0x0C // position of runtime code in bytecode
PUSH1 0x00 // write to memory position 0
CODECOPY   // copies the bytecode
PUSH1 0x05 // 5 bytes
PUSH1 0x00 // read from memory position 0
RETURN     // returns the code copied above
```

Again the position is `0x0C` because the initialization code is 12 bytes. So our initialization bytecodes are `0x6005600C60003960056000F3` and the runtime bytecodes are `0x60006000FD`. The calldata will be these concatenated: `0x6005600C60003960056000F360006000FD`.

## Puzzle 9

```js
00      0x36        CALLDATASIZE
01      0x6003      PUSH1 0x03
03      0x10        LT
04      0x6009      PUSH1 0x09
06      0x57        JUMPI
07      0xFD        REVERT
08      0xFD        REVERT
09      0x5B        JUMPDEST
10      0x34        CALLVALUE
11      0x36        CALLDATASIZE
12      0x02        MUL
13      0x6008      PUSH1 0x08
15      0x14        EQ
16      0x6014      PUSH1 0x14
18      0x57        JUMPI
19      0xFD        REVERT
20      0x5B        JUMPDEST
21      0x00        STOP
```

We start with a small `JUMPI` that requires `3 < CALLDATASIZE` so our calldata is larger than 3 bytes. Afterwards, we multiply our `CALLVALUE` and `CALLDATASIZE`, which is expected to be 8. Simply, we will send a 4 byte calldata with 2 Wei call value.

## Puzzle 10

```js
00      0x38          CODESIZE
01      0x34          CALLVALUE
02      0x90          SWAP1
03      0x11          GT
04      0x6008        PUSH1 0x08
06      0x57          JUMPI
07      0xFD          REVERT
08      0x5B          JUMPDEST
09      0x36          CALLDATASIZE
10      0x610003      PUSH2 0x0003
13      0x90          SWAP1
14      0x06          MOD
15      0x15          ISZERO
16      0x34          CALLVALUE
17      0x600A        PUSH1 0x0A
19      0x01          ADD
20      0x57          JUMPI
21      0xFD          REVERT
22      0xFD          REVERT
23      0xFD          REVERT
24      0xFD          REVERT
25      0x5B          JUMPDEST
26      0x00          STOP
```

The first `CODESIZE` is the size of this puzzle itself, which is `1B` (28 bytes). Next it swaps the `CALLVALUE` with it, and runs `GT`. In effect, this checks if `CODESIZE > CALLVALUE`.

After the successfull `JUMPI`, we are doing a `CALLDATASIZE MOD 0x003 == 0` operation. We want this to be true for the next `JUMPI` to work, so our calldata size must be a multiple of 3.

The destination of `JUMPI` is defined by `CALLVALUE ADD 0x0A`, which should add up to `0x19`. In decimals, `0x0A` is 10 and `0x19` is 25, so our `CALLVALUE` should be 15.

# More EVM Puzzles

> [More EVM Puzzles](https://github.com/fvictorio/evm-puzzles/) are a collection of puzzles, similar to [EVM Puzzles](https://github.com/fvictorio/evm-puzzles/) by [Franco Victorio](https://github.com/fvictorio). In each puzzle, the objective is to have the code `STOP`, rather than `REVERT`.

## Puzzle 1

```js
00      36      CALLDATASIZE
01      34      CALLVALUE
02      0A      EXP
03      56      JUMP
04      FE      INVALID
05      FE      INVALID
06      FE      INVALID
07      FE      INVALID
08      FE      INVALID
09      FE      INVALID
0A      FE      INVALID
0B      FE      INVALID
0C      FE      INVALID
0D      FE      INVALID
0E      FE      INVALID
0F      FE      INVALID
10      FE      INVALID
11      FE      INVALID
12      FE      INVALID
13      FE      INVALID
14      FE      INVALID
15      FE      INVALID
16      FE      INVALID
17      FE      INVALID
18      FE      INVALID
19      FE      INVALID
1A      FE      INVALID
1B      FE      INVALID
1C      FE      INVALID
1D      FE      INVALID
1E      FE      INVALID
1F      FE      INVALID
20      FE      INVALID
21      FE      INVALID
22      FE      INVALID
23      FE      INVALID
24      FE      INVALID
25      FE      INVALID
26      FE      INVALID
27      FE      INVALID
28      FE      INVALID
29      FE      INVALID
2A      FE      INVALID
2B      FE      INVALID
2C      FE      INVALID
2D      FE      INVALID
2E      FE      INVALID
2F      FE      INVALID
30      FE      INVALID
31      FE      INVALID
32      FE      INVALID
33      FE      INVALID
34      FE      INVALID
35      FE      INVALID
36      FE      INVALID
37      FE      INVALID
38      FE      INVALID
39      FE      INVALID
3A      FE      INVALID
3B      FE      INVALID
3C      FE      INVALID
3D      FE      INVALID
3E      FE      INVALID
3F      FE      INVALID
40      5B      JUMPDEST
41      58      PC
42      36      CALLDATASIZE
43      01      ADD
44      56      JUMP
45      FE      INVALID
46      FE      INVALID
47      5B      JUMPDEST
48      00      STOP
```

In this puzzle, we have two jumps to be concerned:

- The first jump targets destination `callvalue ^ calldatasize`. We want this to be `0x40` which is `2 ** 6`. There are several ways we can obtain this.
- The second jump targets `calldatasize + programcounter`. The `PC` instruction will return the line number that it is called at, in this case `41`. To reach `47`, we need our calldata size to be 6. So, for the previous jump target that means we need a calldata value of `2`, simply giving us `2 ** 6`.

## Puzzle 2

```js
00      36        CALLDATASIZE
01      6000      PUSH1 00
03      6000      PUSH1 00
05      37        CALLDATACOPY
06      36        CALLDATASIZE
07      6000      PUSH1 00
09      6000      PUSH1 00
0B      F0        CREATE
0C      6000      PUSH1 00
0E      80        DUP1
0F      80        DUP1
10      80        DUP1
11      80        DUP1
12      94        SWAP5
13      5A        GAS
14      F1        CALL
15      3D        RETURNDATASIZE
16      600A      PUSH1 0A
18      14        EQ
19      601F      PUSH1 1F
1B      57        JUMPI
1C      FE        INVALID
1D      FE        INVALID
1E      FE        INVALID
1F      5B        JUMPDEST
20      00        STOP
```

Don't be afraid of what is going on above there. We simply create a contract, and call it; expecting the call to return something with the size `0x0A` as a result. So, that is simply what we will do!

```c
// init
PUSH1 0x0a // runtime code is 10 bytes
PUSH1 0x0C // runtime code starts at 0x0C
PUSH1 0x00 // copy to 0th memory slot
CODECOPY
PUSH1 0x0a // runtime code is 10 bytes
PUSH1 0x00 // return from 0th memory slot
RETURN

// runtime
PUSH1 0x0a // return 12 bytes
DUP1       // offset irrelevant
RETURN
```

## Puzzle 3

```js
00      36        CALLDATASIZE
01      6000      PUSH1 00
03      6000      PUSH1 00
05      37        CALLDATACOPY
06      36        CALLDATASIZE
07      6000      PUSH1 00
09      6000      PUSH1 00
0B      F0        CREATE
0C      6000      PUSH1 00
0E      80        DUP1
0F      80        DUP1
10      80        DUP1
11      93        SWAP4
12      5A        GAS
13      F4        DELEGATECALL
14      6005      PUSH1 05
16      54        SLOAD
17      60AA      PUSH1 AA
19      14        EQ
1A      601E      PUSH1 1E
1C      57        JUMPI
1D      FE        INVALID
1E      5B        JUMPDEST
1F      00        STOP
```

This one is similar to the previous, again a contract is created but this time a delegate-call is made. After that, it is checked whether the 5th slot in the storage is equal to `0xAA`. So, we just have to write a contract that sets `0xAA` to slot 5.

```c
// init
PUSH1 0x05 // 5 byte runtime code
PUSH1 0x0C // runtime code position
PUSH1 0x00 // write to memory position 0
CODECOPY   // copies the bytecode
PUSH1 0x05 // 5 byte runtime code
PUSH1 0x00 // read from memory position 0
RETURN     // returns the code copied above
// runtime
PUSH1 0xAA // value
PUSH1 0x05 // key
SSTORE     // store command
```

In bytecode terms: `0x6005600c60003960056000f360aa600555` does the trick.

## Puzzle 4

```js
00      30        ADDRESS
01      31        BALANCE
02      36        CALLDATASIZE
03      6000      PUSH1 00
05      6000      PUSH1 00
07      37        CALLDATACOPY
08      36        CALLDATASIZE
09      6000      PUSH1 00
0B      30        ADDRESS
0C      31        BALANCE
0D      F0        CREATE
0E      31        BALANCE
0F      90        SWAP1
10      04        DIV
11      6002      PUSH1 02
13      14        EQ
14      6018      PUSH1 18
16      57        JUMPI
17      FD        REVERT
18      5B        JUMPDEST
19      00        STOP
```

First, assuming that our account has 0 balance, the balance of this address during runtime will be equal to the `callvalue`. Then, notice that `CREATE` has value equal to `callvalue`, meaning that it is consuming all our balance.

Then, we check the balance of that deployed contract, and expect it to be half of the initial balance (calculated in the first two lines). To make that possible, we simply have to make our contract send half of the `callvalue` to somewhere else.

```c
// (call:7) retSize
PUSH1 0x00
// (call:6) retOffset
DUP1
// (call:5) argsSize
DUP1
// (call:4) argsOffset
DUP1
// (call:3) find half of call value (assuming it is even)
PUSH1 0x02
CALLVALUE
DIV
// (call:2) address (0x0)
DUP2
// (call:1) remaining gas
GAS
// send money!
CALL

// return nothing
PUSH1 0x00
DUP1
RETURN     // returns the code copied above
```

The initialization code does not have to return anything, so we can return right after making our call. To sum up, our calldata is `0x600080808060023404815af1600080f3` and the callvalue can be any even number!

## Puzzle 5

```js
00      6020      PUSH1 20
02      36        CALLDATASIZE
03      11        GT
04      6008      PUSH1 08
06      57        JUMPI
07      FD        REVERT
08      5B        JUMPDEST
09      36        CALLDATASIZE
0A      6000      PUSH1 00
0C      6000      PUSH1 00
0E      37        CALLDATACOPY
0F      36        CALLDATASIZE
10      59        MSIZE
11      03        SUB
12      6003      PUSH1 03
14      14        EQ
15      6019      PUSH1 19
17      57        JUMPI
18      FD        REVERT
19      5B        JUMPDEST
1A      00        STOP
```

In the beginning, we simply need to have a calldata that is greater than `0x20`. In the second part, there is a `CALLDATACOPY` followed by `MSIZE`. Now, `CALLDATACOPY` will copy the calldata into memory, but note that this will happen in 32-byte chunks. `MSIZE` will return the highest reached offset in memory. Suppose our calldata size is larger than `0x20` but less than `0x40`. When written into memory, even if calldata size is less than `0x40` the highest memory offset will be `0x40`, due to it being written in chunks of 32 bytes.

We want `MSIZE - CALLDATASIZE` to be equal to 3, so we can have a calldata of size `0x3D` and that would be ok! Here is a calldata of that size: `0x11223344112233441122334411223344112233441122334411223344112233441122334411223344112233441122334411223344112233441122334411`. I just copy-pasted chunks of 4 byte `11223344`s and then removed 3 bytes from the end.

## Puzzle 6

```js
00      7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0      PUSH32 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
21      34                                                                      CALLVALUE
22      01                                                                      ADD
23      6001                                                                    PUSH1 01
25      14                                                                      EQ
26      602A                                                                    PUSH1 2A
28      57                                                                      JUMPI
29      FD                                                                      REVERT
2A      5B                                                                      JUMPDEST
2B      00                                                                      STOP
```

Here, we have a HUGE number `0xFF...F0` and we add some callvalue to it, expecting the result to be `0x01`. How is that possible? Well, it's the good ol' overflow issue right here. If we add `0x0F` to it, the whole thing becomes `0xFF..FF`. So, we add just 1 more to that and it becomes `0x00..00`. To get to `0x00..01`, we just add once more. Basically, our callvalue is 17 (`0x0F + 0x01 + 0x01`).

## Puzzle 7

```js
00      5A        GAS
01      34        CALLVALUE
02      5B        JUMPDEST
03      6001      PUSH1 01
05      90        SWAP1
06      03        SUB
07      80        DUP1
08      6000      PUSH1 00
0A      14        EQ
0B      6011      PUSH1 11
0D      57        JUMPI
0E      6002      PUSH1 02
10      56        JUMP
11      5B        JUMPDEST
12      5A        GAS
13      90        SWAP1
14      91        SWAP2
15      03        SUB
16      60A6      PUSH1 A6
18      14        EQ
19      601D      PUSH1 1D
1B      57        JUMPI
1C      FD        REVERT
1D      5B        JUMPDEST
1E      00        STOP
```

In the first, we have a `CALLVALUE - 0x01 == 0x00` check. If true, we go to line `0x11`; otherwise, we go to line `0x02`.

- At `0x011`, a `GAS - GAS'` (where `GAS'` is the one from line `0x00`) is calculated and we win if that is equal to `A6`. In other words, we must have spent `0xA6` gas to get here.
- At `0x02`, we basically do the same things again. In fact, this whole thing is a for-loop that loops as much as your `CALLVALUE`.

Looking at these together, we must be looping for a while so that the gas spent is `0xA6` when that check happens. `0xA6 = 100 * 16 + 6 = 166`. A callvalue of 4 does the trick.

(TODO GAS CALCULATIONS)

## Puzzle 8

```js
00      34        CALLVALUE
01      15        ISZERO
02      19        NOT
03      6007      PUSH1 07
05      57        JUMPI
06      FD        REVERT
07      5B        JUMPDEST
08      36        CALLDATASIZE
09      6000      PUSH1 00
0B      6000      PUSH1 00
0D      37        CALLDATACOPY
0E      36        CALLDATASIZE
0F      6000      PUSH1 00
11      6000      PUSH1 00
13      F0        CREATE
14      47        SELFBALANCE
15      6000      PUSH1 00
17      6000      PUSH1 00
19      6000      PUSH1 00
1B      6000      PUSH1 00
1D      47        SELFBALANCE
1E      86        DUP7
1F      5A        GAS
20      F1        CALL
21      6001      PUSH1 01
23      14        EQ
24      6028      PUSH1 28
26      57        JUMPI
27      FD        REVERT
28      5B        JUMPDEST
29      47        SELFBALANCE
2A      14        EQ
2B      602F      PUSH1 2F
2D      57        JUMPI
2E      FD        REVERT
2F      5B        JUMPDEST
30      00        STOP
```

The first jump will occur if callvalue is non-zero, because `ISZERO` will return `0` and `NOT` will make it to be `1` again, thus enabling the `JUMPI` on line `0x05`.

Afterwards, a contract is created with value `SELFBALANCE` (which may be assumed equal to callvalue) and then it is called. The returned data is expected to be equal to `0x01`. Finally, the balance after making the call is expected to equal the initial balance.

Considering that `SELFBALANCE` is used during contract creation, and then it is called afterwards, the call should send the given balance back to the deployer, otherwise self-balance of the caller will be 0. In doing so, the deployed code should also return `0x01` as return data.

```c
// init
PUSH1 0x0F  // runtime code size
PUSH1 0x0C  // runtime code position
PUSH1 0x00  // write to memory position 0
CODECOPY    // copies the bytecode
PUSH1 0x0F  // runtime code size
PUSH1 0x00  // read from memory position 0
RETURN      // returns the code copied above
// runtime
PUSH1 0x01  // (mstore:2) value = 0x01
PUSH1 0x80  // (mstore:1) offset, 0x80 as required by EVM
MSTORE
PUSH1 0x01  // (call:7) retSize 1 byte
PUSH1 0x80  // (call:6) retOffset
DUP1        // (call:5) argsSize
DUP1        // (call:4) argsOffset
SELFBALANCE // (call:3) return entire balance
CALLER      // (call:2) address is msg.sender
GAS         // (call:1) remaining gas
CALL        // sends selfbalance to msg.sender
```

Our calldata is as written above, which results in a contract to be deployed, which returns `0x01` and forwards all it's balance to the caller when it is called.

## Puzzle 9

```js
00      34        CALLVALUE
01      6000      PUSH1 00
03      52        MSTORE
04      6020      PUSH1 20
06      6000      PUSH1 00
08      20        SHA3
09      60F8      PUSH1 F8
0B      1C        SHR
0C      60A8      PUSH1 A8
0E      14        EQ
0F      6016      PUSH1 16
11      57        JUMPI
12      FD        REVERT
13      FD        REVERT
14      FD        REVERT
15      FD        REVERT
16      5B        JUMPDEST
17      00        STOP
```

First, our callvalue is stored in the 0th slot of memory. Then, 20 bytes of this value is given to SHA3 as input. The resulting hash is shifted `0xF8` times, meaning `248` times, so there remains just a single byte as a result (`256 - 248 = 8`). We want this to equal `0xA8`.

All we have to do is then find a callvalue such that it's SHA3's most significant byte is `0xA8`. Considering that the hash output is close to uniformly random, we have about `1/256` chance to guess it correctly.

We can write a script for that, but I will just give the answer to be 47 here, which results in SHA3 `a813484aef6fb598f9f753daf162068ff39ccea4075cb95e1a30f86995b5b7ee`.

## Puzzle 10

```js
00      6020                                                                    PUSH1 20
02      6000                                                                    PUSH1 00
04      6000                                                                    PUSH1 00
06      37                                                                      CALLDATACOPY
07      6000                                                                    PUSH1 00
09      51                                                                      MLOAD
0A      7FF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0      PUSH32 F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
2B      16                                                                      AND
2C      6020                                                                    PUSH1 20
2E      6020                                                                    PUSH1 20
30      6000                                                                    PUSH1 00
32      37                                                                      CALLDATACOPY
33      6000                                                                    PUSH1 00
35      51                                                                      MLOAD
36      17                                                                      OR
37      7FABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB      PUSH32 ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB
58      14                                                                      EQ
59      605D                                                                    PUSH1 5D
5B      57                                                                      JUMPI
5C      FD                                                                      REVERT
5D      5B                                                                      JUMPDEST
5E      00                                                                      STOP
```

In the first part, a 32-byte are loaded from the calldata. Then, this is bitwise-AND'ed with 32-byte `0xF0F0..F0` of 32 bytes. Next, another 32-byte is read from the calldata and it is bitwise-OR'ed with the previous result. We require this final result to be equal to `0xABAB..AB`.

We can do this as follows:

```c
0xA0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 // calldata bytes 0..31
0xF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 // given by challenge
// --------------------------------------------------------------- AND
0xA0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 // result from previous
0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B // calldata bytes 32..63
// --------------------------------------------------------------- OR
0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB // our result
0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB // expected result
```

So our calldata should be `0xA0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A00B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B`