abi_decode doesn't correctly decode arrays of uint256
- Dominant language
- Haskell
- Stars
- 113
- Forks
- 9
- Avg merge
- 4d 9h
- Merged PRs (30d)
- 1
Description
BUG: after fixing the buffer origin, the public abi_decode function reaches the array decoder correctly.
That decoder mistakes the top-level offset (32) for the array length and never decodes the elements.
Expected result: (3, 11). Actual result: (32, 0).
```solidity
import std.{*};
import std.dispatch.{*};
import std.opcodes.{mload};
// workaround for https://github.com/argotorg/solcore/issues/577
// A local view of memory(bytes) with the AbiDecodeBufferOrigin fix applied.
// Its WordReader begins at [payload], not at [length | payload].
data PayloadMemoryBytes = PayloadMemoryBytes(word);
instance PayloadMemoryBytes:HasWordReader(MemoryWordReader) {
function getWordReader(x: PayloadMemoryBytes) -> MemoryWordReader {
match x {
| PayloadMemoryBytes(ptr) => return MemoryWordReader(ptr + 32);
}
}
}
contract MemoryArrayDecoder {
public function decodeArray() -> (uint256, uint256) {
let original: memory(DynArray(uint256)) = [11, 22, 33];
let encoded = abi_encode(original);
let fixedInput = PayloadMemoryBytes(Typedef.rep(encoded));
let decoded: memory(DynArray(uint256)) = abi_decode(
fixedInput,
Proxy:Proxy(memory(DynArray(uint256))),
Proxy:Proxy(MemoryWordReader)
);
return (uint256(mload(Typedef.rep(decoded))), decoded[uint256(0)]);
}
}
```
SOLUTION: have the memory-array decoder follow the top-level dynamic offset, read the tail length, and restore its element loop.
Decode each element from the array-region base so offsets for dynamic elements remain relative to thecorrect origin;
reject unsupported element layouts instead of returning zeros.
PATCH: https://github.com/argotorg/solcore-rs/blob/8d5576699a8ca139e43b72c39f4545d3d2312de1/std/std.solc#L1707
```diff
- let arrayPtr = WordReader.advance(ptr, currentHeadOffset);
+ let tail = WordReader.read(WordReader.advance(ptr, currentHeadOffset));
+ let arrayPtr = WordReader.advance(ptr, tail); // then restore the decode loop
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in std/std.solc around line 1707 and reproduce the issue through MemoryArrayDecoder.decodeArray using the example in the report. Verify that the decoded array returns (3, 11), that its elements are read from the correct array region, and that unsupported element layouts do not silently return zeros.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100