-
Notifications
You must be signed in to change notification settings - Fork 187
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
Runtime decoding checks #440
Conversation
42ffdbb
to
361c36d
Compare
Codecov Report
@@ Coverage Diff @@
## master #440 +/- ##
==========================================
+ Coverage 87.32% 87.64% +0.31%
==========================================
Files 77 77
Lines 5081 5235 +154
==========================================
+ Hits 4437 4588 +151
- Misses 644 647 +3
Continue to review full report at Codecov.
|
crates/yulgen/tests/snapshots/yulgen__abi_pack_calldata_function.snap
Outdated
Show resolved
Hide resolved
crates/yulgen/tests/snapshots/yulgen__abi_pack_mem_function.snap
Outdated
Show resolved
Hide resolved
fb72692
to
4053b13
Compare
if iszero(eq(data_start_offset_1, 192)) { revert(0, 0) } | ||
if iszero(eq(data_start_offset_2, data_end_offset_1)) { revert(0, 0) } | ||
if iszero(eq(data_start_offset_5, data_end_offset_2)) { revert(0, 0) } | ||
if iszero(eq(encoding_size, data_end_offset_5)) { revert(0, 0) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cburgdorf the Solidity code I looked at didn't revert with any specific values, but it looks like they plan on adding it. I'll create an issue to track this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I didn't notice until now that you had a comment on this. Anyway, 0x99
is good for now 👍
max: yul::Expression, | ||
}, | ||
} | ||
|
||
/// Returns an expression that encodes the given values and returns a pointer to | ||
/// the encoding. | ||
pub fn encode<T: AbiEncoding>(types: &[T], vals: Vec<yul::Expression>) -> yul::Expression { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sbillig I'll follow up this PR with another one tidying up these traits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
My only comment would be to think about introducing our own panic code for when we revert from these checks and use revert_with_panic(..)
. I basically think we should never revert with zero data unless for when a user writes revert
with no extra data. This should improve the debugging story for developers as tooling can map these panic codes to a user friendly error which might save a developer from having to manually step to a debugger to find out where the revert came from.
crates/tests/src/features.rs
Outdated
// add a byte | ||
let mut tampered_data = data.clone(); | ||
tampered_data.push(42); | ||
harness.test_call_reverts(&mut executor, tampered_data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you said that solidity also just reverts with zero data for these checks but I wonder if that's just a todo on their end and if we should just introduce a panic code to be used for these reverts. From a developer perspective I think reverts with zero information are very annoying and a single panic code used for all calldata violation can already be quite helpful during debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure it's a todo.
Any suggestions for the specific panic code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the panic code 0x99
for now.
crates/yulgen/src/operations/abi.rs
Outdated
pub fn check_left_padding(size_bits: yul::Expression, val: yul::Expression) -> yul::Statement { | ||
statement! { | ||
if (iszero((is_left_padded([size_bits], [val])))) { | ||
(revert(0, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just re-stating what I commented above on the test code. I think we should consider introducing our own panic code and then do a revert_with_panic(<some-code>)
. Basically I think the only time where we should revert with zero data is when someone actually uses revert
with no data. In all other circumstances we should revert with a panic code and we should go with whatever panic code Solidity uses and if they don't use one we make up our own.
We now check the following when decoding data:
u8[n]
) is equal to the size of the array.Decoding function walk through:
fe/crates/yulgen/tests/snapshots/yulgen__abi_decode_data_u256_bytes_string_bool_address_bytes_calldata_function.snap
Lines 6 to 31 in 169e95f
Note: At the moment, we have separate
decode_data_...
anddecode_component_tuple_...
functions. In the future when we add support for recursive encoding, we will just be using adecode_tuple_...
function.encoding size check
We check that the size of the entire encoding fits within known bounds.
head offset section
Head offsets are known at compile-time, so we just assign a literal value.
component decoding section
We call the decoding function for each component value. The decoding functions return the decoded value along with data section offsets for dynamically sized values.
data offset checks section
We check that the offsets given in the last step are consistent with one another. Basically we're checking that each encoding starts where the last one ends. For the first offset, we check that it starts where the head section ends (
192
in this case).return section
To-Do
OPTIONAL: Update Spec if applicable
Add entry to the release notes (may forgo for trivial changes)
Clean up commit history