In this track: Dynamic ABI and nested layouts
advanced · 5 MIN READ

Bounds checks in ABI decoders

Every length calculation must stay inside the available input.

LET’S PICTURE IT

A librarian checks both the requested starting page and the number of pages requested.

SEE IT FOR YOURSELF
Follow a dynamic string from head to tailStep 1 / 4
Follow a dynamic string from head to tailArgument headbyte 0 · offset 32hex word ends in 20String tailstarts at byte 32length + contentPositions are measured from argument byte zero, excluding any selectorOffset destinationargument byte 32read a length wordLength = 5hello is five UTF-8 bytescontent starts at byte 64A length word and an offset word have different jobsContent word · argument byte 6468 65 6c 6c 6f5 payload bytes27 padding bytesBlocks are schematic; their drawn widths do not represent the exact byte ratioHeadoffset: 32argument byte 0Tail lengthlength: 5argument byte 32Tail contenthello + paddingargument byte 6432 + 32 + 32 = 96 bytesWith a four-byte selector, total calldata length is 100 bytes

This example encodes one string parameter with value hello. A dynamic argument uses an offset in its head, even when it is the only argument.

Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.

Validate the first read

A decoder must establish that the offset and length words are available before reading them. Checking only the final content is too late if the length read itself is invalid.

Handle arithmetic safely

Computing base plus offset and start plus length must not wrap around an integer boundary. A very large number must not turn into a small apparently safe position.

Account for nested structures

Arrays add element counts and repeated reads. Bounds checks must apply recursively to nested values, rather than trusting the outer array merely because its first word is readable.

Add resource limits in applications

Even structurally decodable data can be expensive to display or process. A local tool can limit input size and output work while explaining that these are tool limits, not new ABI rules.

Trace a local example

types: bytes[]
values: [["0x01","0x0203"]]
no function selector prefix

word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000000000000000020

word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000002

word 2 · argument offset 64 bytes
0x0000000000000000000000000000000000000000000000000000000000000040

word 3 · argument offset 96 bytes
0x0000000000000000000000000000000000000000000000000000000000000080

word 4 · argument offset 128 bytes
0x0000000000000000000000000000000000000000000000000000000000000001

word 5 · argument offset 160 bytes
0x0100000000000000000000000000000000000000000000000000000000000000

word 6 · argument offset 192 bytes
0x0000000000000000000000000000000000000000000000000000000000000002

word 7 · argument offset 224 bytes
0x0203000000000000000000000000000000000000000000000000000000000000

Each element has a separate dynamic tail with its own byte length.

TURN UNDERSTANDING INTO PRACTICEOpen the ABI encoder →
QUICK CHECK · NO PRESSURE

Is checking the outer length enough for nested dynamic data?

Your progress stays in this browser.
Keep exploring the original referenceSolidity documentation ↗

Original explanations by EtherTools. Examples are educational and source-linked; this site is independent of the Ethereum Foundation. Our approach.