Skip to content

Instantly share code, notes, and snippets.

@frangio
Last active December 19, 2024 15:07
Show Gist options
  • Save frangio/195edcde4773df875ac3a2ad542cd871 to your computer and use it in GitHub Desktop.
Save frangio/195edcde4773df875ac3a2ad542cd871 to your computer and use it in GitHub Desktop.
@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