Last active
December 19, 2024 15:07
-
-
Save frangio/195edcde4773df875ac3a2ad542cd871 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@frangio: is there a list of all the consistency/security checks abi coder v2 | |
does? e.g. that offsets are within bounds | |
@ekpyron: We're currently lacking exhaustive documentation on it, unfortunately | |
- it came up a few times recently and we want to improve docs around it, | |
though. But as a brief informal summary: Calldata validation involves at least | |
(I may be missing something else myself out of my head) range-checks for | |
values, bounds-checks and size-checks for arrays and bounds checks against | |
overall calldata size. In particular, what's lacking documentation is indeed | |
when precisely it happens. For performance reasons, we don't necessarily | |
descend into all types in calldata completely on contract entry - calldata | |
validation is performed lazily in layers and only the outermost layer is | |
validated. However, since for an external entry point with memory arguments we | |
do need to perform a deep copy, this counts as deep access and validation is | |
implicitly performed immediately. So for a nested array in calldata, validation | |
of the inner array's properties only occurs on access to the outer array, while | |
if the nested array is declared as memory array, deep validation will be | |
performed right away. | |
@frangio: so if i have a calldata array of structs, are the members of the | |
struct validated lazily? i.e., when accessing an index of the array `xs[i]`? | |
@ekpyron: If an array of structs is passed as an argument | |
`function f(S[] calldata x) public`, what happens immediately is the check that | |
the size of the array is valid and the array (i.e. its heads if `S` is | |
dynamically encoded itself) fit into calldata - further validation is deferred | |
to accesses like `x[i]`, yes. | |
@ekpyron: Or even further :-). For `struct S { uint8 i; }`, the access `x[0]` | |
merely checks that the struct fits - only `x[0].i` reverts if it's out of | |
range. | |
@frangio: just to clarify i assume this is valid for any `S[] calldata x` i get | |
my hands on, not necessarily a direct argument of a public function | |
@ekpyron: Yes - it happens during argument decoding. If you | |
assembly-manufacture a pointer to it, the outer validation will be skipped - | |
but you still get a revert on `x[0].i` if that's out of range. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment