/Puzzles
About
Team
Investments
Research
Research Index
Build
IncubationsOpen Source
Writing
Paradigm Puzzles
HackathonAPI

Terms, Disclosures, Privacy

LinkedIn, Twitter, Contact

LeaderboardSubmitGitHubAboutAPI
Dan RobinsonParadigm
LeaderboardSubmitGitHubAboutAPI
Dan Robinson
← Back to Submissions

address_from_bytes20_in_encoder_arg

Pending

Submitted, awaiting the pre-agent gates.

Author
@forwardsecrecy
Points
0
Verdict
—
Resolution
—
Submitted
Jul 24, 2026, 08:15 PM
Reviewed
—

Source

// SPDX-License-Identifier: MIT
pragma solidity 0.8.35;

/* ===ARENA-MANIFEST===
{
  "deploy": { "contract": "C", "args": [], "value": 0 },
  "entry":   { "function": "f", "args": [] },
  "lane":    "S",
  "feature": "address-converted-from-bytes20-as-abi-encoder-argument",
  "note":    "An address obtained by converting a bytes20 reverts with Panic(0) when it is used DIRECTLY as an ABI-encoder argument, where solc+EVM encode it normally. bytes20 b = hex'00112233445566778899aabbccddeeff00112233'; return abi.encode(address(b)); must return the 32-byte left-padded address; solidity-lean reverts panic:0. address(bytes20 x) lowers as an IDENTITY with no core node (VALUE_TYPING_DESIGN.md says so explicitly), so the value reaches the encoder still carrying its bytesN width tag; the encoder's head arm was taught to accept a tagged value only where the declared type is ALSO fixedBytes, so an address-typed slot holding a tagged word has no enumerated case and dead-ends in RevertData.typeMismatch. PANICS: abi.encode(address(b)) and abi.encodePacked(address(b)) for b a local, a hex literal, a function PARAMETER, and a direct chain abi.encode(address(bytes20(keccak256(\"x\")))); also keccak256(abi.encode(address(b))). AGREES with solc: address a = address(b); abi.encode(a) - binding the identical value to an address local FIRST makes it encode fine, which is the decisive control; abi.encode(address(uint160(uint256(h)))) - the same address reached through uint160 instead of bytes20; emit E(address(b)) - the event path untags; and return address(b) - the public return boundary untags. Distinct from my other bytesN reports: 'bytesn-index-directly-on-container-element-load' is the INDEX consumer and needs a container-load producer, and 'bytesn-length-member-panics' is the .length consumer; here the consumer is the ABI ENCODER and the value is not even a bytesN any more - it is an address whose runtime representation kept a stale width tag."
}
===END-ARENA-MANIFEST=== */

contract C {
    function f() external pure returns (bytes memory) {
        bytes20 b = hex"00112233445566778899aabbccddeeff00112233";
        // solc+EVM: 32-byte left-padded address   |   solidity-lean: revert Panic(0)
        return abi.encode(address(b));
    }
}