Challenge:
Our tenth and final challenge is located in /puzzles/puzzle_10.json. Challenge 10 contains the following:
{
"code": "38349011600857FD5B3661000390061534600A0157FDFDFDFD5B00",
"askForValue": true,
"askForData": true
}
Hint 1:
The corresponding EVM opcodes are:
CODESIZE
CALLVALUE
SWAP1
GT
PUSH1 08
JUMPI
REVERT
JUMPDEST
CALLDATASIZE
PUSH2 0003
SWAP1
MOD
ISZERO
CALLVALUE
PUSH1 0A
ADD
JUMPI
REVERT
REVERT
REVERT
REVERT
JUMPDEST
STOP
Hint 2:
We have 3 new opcodes here: GT, MOD, and ISZERO.
GT checks that the value on the top of the stack
is greater than the value directly below it on the stack.
It will place the result (1 for true or 0 for false)
on the top of the stack.
MOD performs modulo arithmetic on the top two
values on the stack and places the result
on top of the stack
ISZERO checks if the value on the top of the stack is 0.
It will place the result (1 for true or 0 for false)
on the top of the stack.
What should our calldata and call value be so that
we can pass the GT comparison check and return a value of 0
from our MOD operation in order to jump over all
of the REVERT opcodes?
Hint 3:
CODESIZE //Offset 0
CALLVALUE //Offset 1
SWAP1 //Offset 2
GT //Offset 3
PUSH1 08 //Offset 4
JUMPI //Offset 6
REVERT //Offset 7
JUMPDEST //Offset 8
CALLDATASIZE //Offset 9
PUSH2 0003 //Offset A
SWAP1 //Offset D
MOD //Offset E
ISZERO //Offset F
CALLVALUE //Offset 10
PUSH1 0A //Offset 11
ADD //Offset 13
JUMPI //Offset 14
REVERT //Offset 15
REVERT //Offset 16
REVERT //Offset 17
REVERT //Offset 18
JUMPDEST //Offset 19
STOP //Offset 1A
Solution:
Because of the swap need our call value to be less than our
code size. The code size is 0x1b, so any value below that
will pass this first check.
Next, we need our call data size (in bytes) to satisfy this
equation:
3 % X = 0
where X is the size of our call data
So, we can choose any multiple of 3 for byte size of our call data
to pass this check.
Finally, we our call value to satisfy this equation:
0x0A + X = 0x19
Where X is the call value in wei
Putting this all together, we can solve this by passing in
any 3 bytes of data for call data and the decimal value 15
for our call value.
Solution:
calldata: 0xFFFFFF call value: 15