Skip to content

Commit df48423

Browse files
authored
Merge pull request #635 from ethereum/raw-bytecode-doc
Adding an example using raw bytecodes to equivalence checking tutorial
2 parents 1425d9c + cbd48bc commit df48423

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

doc/src/equivalence-checking-tutorial.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,76 @@ command line, although this can become cumbersome:
138138
```shell
139139
$ hevm equivalence --code-a "6080604052348015600e575f80fd5b50600436106026575f3560e01c8063881fc77c14602a575b5f80fd5b60306032565b005b5f600190506002811460455760446048565b5b50565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea26469706673582212208c57ae04774d9ebae7d1d11f9d5e730075068bc7988d4c83c6fed85b7f062e7b64736f6c634300081a0033" --code-b "6080604052348015600e575f80fd5b50600436106030575f3560e01c806385c2fc7114603457806386ae330914603c575b5f80fd5b603a6044565b005b60426055565b005b60025f541460535760526066565b5b565b60035f541460645760636066565b5b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea2646970667358221220bd2f8a1ba281308f845e212d2b5eceab85e029909fa2409cdca7ede039bae26564736f6c634300081a0033"
140140
```
141+
142+
## Working with Raw Bytcode
143+
144+
When doing equivalance checking, the returndata of the two systems are
145+
compared, and the calldata is set to be symbolic. This allows us to compare raw
146+
bytecode as well -- the code does not need to adhere to the Solidity [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html).
147+
148+
The following contract is written in raw assembly. It takes
149+
the 1st byte of the calldata, multiplies it by 0, and stores it in memory, then
150+
returns this value:
151+
152+
```
153+
PUSH1 0x00
154+
CALLDATALOAD
155+
PUSH1 0x00
156+
MUL
157+
PUSH1 0x00
158+
MSTORE
159+
PUSH1 0x01
160+
PUSH1 0x00
161+
RETURN
162+
```
163+
164+
This can be compiled into bytecode via e.g. [evm.codes](https://evm.codes/),
165+
which allows us to both simulate this, and to get a bytecode for it: `60003560000260005260016000f3`. Notice that since anything multiplied by 0 is zero, for any calldata, this will put 0 into the returndata.
166+
167+
Let's compare the above code to an assembly contract that simply returns 0:
168+
169+
```
170+
PUSH32 0x0
171+
PUSH1 0x00
172+
MSTORE
173+
PUSH1 0x01
174+
PUSH1 0x00
175+
RETURN
176+
```
177+
178+
This second contract compiles to:
179+
`7f000000000000000000000000000000000000000000000000000000000000000060005260016000f3`.
180+
181+
182+
Let's check whether the two are equivalent:
183+
184+
```shell
185+
$ hevm equivalence --code-a "60003560000260005260016000f3" --code-b "7f000000000000000000000000000000000000000000000000000000000000000060005260016000f3"
186+
Found 1 total pairs of endstates
187+
Asking the SMT solver for 1 pairs
188+
No discrepancies found
189+
```
190+
191+
If however we replace the
192+
```
193+
PUSH32 0x0
194+
```
195+
with
196+
```
197+
PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
198+
```
199+
we get:
200+
201+
```shell
202+
$ hevm equivalence --code-a "60003560000260005260016000f3" --code-b "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005260016000f3"
203+
Found 1 total pairs of endstates
204+
Asking the SMT solver for 1 pairs
205+
Reuse of previous queries was Useful in 0 cases
206+
Not equivalent. The following inputs result in differing behaviours:
207+
-----
208+
Calldata:
209+
Empty
210+
```
211+
212+
Which shows that even with empty calldata, the two are not equivalent: one
213+
returns `0xff` and the other `0x0`.

0 commit comments

Comments
 (0)