New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ecrecover] Legacy codegen cleans dirty storage bits on read but Sol->Yul on write itself #11602
Comments
I'm not sure if this is a "bug" as such. Perhaps sufficient to document in IR breaking changes docs? We already document the fact that dirty storage bits may be retained by the legacy codegen using the following example. But there the "dirtying" is visible to the auditor's eyes unlike the present example (via a call to ecrecover)
|
Whether or not the dirtying is visible or not does not change the issue in my opinion. |
I'm sorry, didn't follow. Is the argument that this issue is not different from the documented example in the comment above (where |
Sorry: I think this is the same issue as the one we already have documented. There are numerous places where memory can get dirty, not only in explicit mstore operations. |
If I understood it correctly, what is being dirtied here via the The fuzzer does not compare memory traces anyway. |
Summary of discussion with Chris on gitter: Most likely explanation for this issue is that the string The main difference between this issue and #12050 is that the dirty bytes are not part of the underlying type i.e., the length of bytes is specified by its first byte. |
In the semantic test below,
I'm not sure where the stray
|
Slightly simpler repro:
I guess there's dirty memory before the assignment to |
Actually:
has the issue without any inline assembly... |
Also happens with a less exotic event...
|
Another simplification:
...this is starting to look somewhat serious to me... |
So do we consider #13045 a complete fix for this or are there potentially more cases that we need to explore? |
Reading through this again, I think #13045 should have been a complete fix, so I'm closing this. |
This test checks the value obtained via inline assembly from the storage slot 32 bytes after the start of storage variable
s0
.Ideally, this slot should return the last byte of the 33-byte bytes array literal that is being assigned to
s0
(which would be the hex of the ascii value ofr
i.e.,0x72
). However, what is actually returned includes "dirty bits" that seem to be from the last argument to theecrecover
call preceeding the storage variable assignment in the constructor.The semantic test above passes via legacy code gen but fails via Yul. Via Yul the return value from
f()
is0x7200...00
.Please note that the legacy codegen does clean up the dirty bits but lazily such that non inline assembly accesses e.g.,
r = s0[32];
returns0x7200...00
as expected i.e., the cleaned up value from the adjacent slot.The text was updated successfully, but these errors were encountered: