ABI coder v1 does not clean dirty array items
Author: Subway2023Created Apr 4, 2024Updated Sep 14, 2026
Labelsbug :bug:documentation :book:codegen errorlow effortlow impactshould have
Description
When using assembly statements to assign a value that exceeds the array range to an array, AbiCoder v1 fails to encode the return value correctly when returning the array. However, AbiCoder v2 does not have this issue.
Environment
- Compiler version: 0.8.25
- Target EVM version (as per compiler settings): No restrictions
- Framework/IDE: Command-line
- EVM execution environment / backend / blockchain client: None
- Operating system: Linux
Steps to Reproduce
# If you comment out this line, AbiCoder v2 will be used by default.
pragma abicoder v1;
contract test {
function f() external returns (uint8[] memory) {
uint8[] memory x = new uint8[](1);
assembly {
mstore(add(x, 0x20), 0x1ff)
}
return x;
}
}1. Build EVM
git clone [email protected]:ethereum/go-ethereum.git
make all2. Get function Signatures
solc C.sol --hashes --overwrite -o hashDirFunction signatures:
26121ff0: f()3. Get bin-runtime
solc --bin-runtime C.sol --overwrite -o binDir608060405234801561000f575f80fd5b5060043610610029575f3560e01c806326121ff01461002d575b5f80fd5b61003561004b565b604051610042919061016c565b60405180910390f35b60605f600167ffffffffffffffff8111156100695761006861018c565b5b6040519080825280602002602001820160405280156100975781602001602082028036833780820191505090505b5090506101ff60208201528091505090565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f60ff82169050919050565b6100e7816100d2565b82525050565b5f6100f883836100de565b60208301905092915050565b5f602082019050919050565b5f61011a826100a9565b61012481856100b3565b935061012f836100c3565b805f5b8381101561015f57815161014688826100ed565b975061015183610104565b925050600181019050610132565b5085935050505092915050565b5f6020820190508181035f8301526101848184610110565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfea26469706673582212205a42b50705af3aa5760eee8c6f23424d2e988432726970a1c5cf3ed9a0111a6064736f6c634300081900334. Run in the EVM
go-ethereum-1.13.11/build/bin/evm --debug --json --code "bin in binDir" --input 26121ff0 run >test.json5. Compare output
output from pragma abicoder v1
{"output":"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001ff","gasUsed":"0x23e"}output from pragma abicoder v2
{"output":"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000ff","gasUsed":"0x3c9"}We can observe that after encoding with AbiCoder v1, the elements in the array are 1ff, whereas after encoding with AbiCoder v2, the array elements are ff
Source: argotorg/solidity