Skip to content

Introduce support for SWAPN, DUPN opcodes according to the EIP 8024 - #16872

Open
rodiazet wants to merge 4 commits into
developfrom
eip-8024
Open

Introduce support for SWAPN, DUPN opcodes according to the EIP 8024#16872
rodiazet wants to merge 4 commits into
developfrom
eip-8024

Conversation

@rodiazet

Copy link
Copy Markdown
Contributor

Description

EIP-8024

AI Disclosure

  • No AI tools were used

Claude Fable 5 (model ID claude-fable-5) was used to make automatic changes.

@rodiazet
rodiazet force-pushed the eip-8024 branch 3 times, most recently from e44ed59 to 16ceb83 Compare July 16, 2026 08:42
Comment thread docs/yul.rst Outdated
Comment on lines +755 to +756
Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L``, ``P``, ``N`` and ``O`` are present since
Frontier, Homestead, Byzantium, Constantinople, Istanbul, London, Paris, Cancun or Osaka respectively.
Frontier, Homestead, Byzantium, Constantinople, Istanbul, London, Paris, Cancun, Osaka or Amsterdam respectively.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add Amsterdam here if you are not adding the one-letter mark?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread libevmasm/Assembly.cpp Outdated
uint8_t encodeDupSwapNImmediate(size_t _depth)
{
solAssert(_depth >= 17 && _depth <= 235);
return static_cast<uint8_t>(_depth + 111);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this overflowing uint8_t? What am I missing here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should because according to spec we have to get % 256. Maybe explicit modulo would be more readable here.

def encode_single(n: int) -> int:
    assert 17 <= n <= 235
    return (n + 111) % 256

@rodiazet
rodiazet force-pushed the eip-8024 branch 2 times, most recently from f730a8c to 2ebc101 Compare July 16, 2026 09:52
@rodiazet
rodiazet requested a review from matheusaaguiar August 4, 2026 09:48
@rodiazet
rodiazet marked this pull request as ready for review August 4, 2026 09:48
@rodiazet
rodiazet requested a review from blishko August 4, 2026 09:48

@matheusaaguiar matheusaaguiar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DupN and SwapN got their own AssemblyItemType while DUP and SWAP are under AssemblyItemType::Operation.
Both versions of Dup/Swap seem to be treated uniformly through the use of factory methods, however in SemanticInformation::breaksCSEAnalysisBlock and GasMeter::estimateMax they are treated differently because of their distinct AssemblyItemType.
They should be treated the same, no?

Also, Changelog entry needed.

@rodiazet

rodiazet commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

DupN and SwapN got their own AssemblyItemType while DUP and SWAP are under AssemblyItemType::Operation. Both versions of Dup/Swap seem to be treated uniformly through the use of factory methods, however in SemanticInformation::breaksCSEAnalysisBlock and GasMeter::estimateMax they are treated differently because of their distinct AssemblyItemType. They should be treated the same, no?

Also, Changelog entry needed.

Right. Fixed. I removed also default from both of these switch statements to prevent similar overlooking next time. I will add changelog entry later as it’s not going to be merged any time soon and rebasing it with changelog entry always requires manual conflict resolving.

rodiazet and others added 4 commits August 6, 2026 10:59
AssemblyItem::dup()/swap() create the stack manipulation items from a
depth argument, and AbstractAssembly::appendDup()/appendSwap() expose
them uniformly to code generators. All call sites that constructed
DUP1-16/SWAP1-16 from a computed depth are converted. No functional
change.

Co-authored-by: Francisco Giordano <fg@frang.io>
Introduce the DUPN and SWAPN instructions with the devnet-3 immediate
encoding, available in legacy bytecode starting from the "amsterdam"
EVM version. The AssemblyItem::dup()/swap() factories now emit them for
depths above 16, extending the reachable stack depth to 235 in legacy
codegen, inline assembly and the Yul code transforms. Includes
assembler, disassembler, optimizer and gas metering support as well as
assembly JSON import/export.

Co-authored-by: Francisco Giordano <fg@frang.io>
Add assembler, disassembler, semantic and code transform tests for DUPN
and SWAPN. Tests whose expectations depend on the stack being limited
to 16 reachable slots are restricted to EVM versions before "amsterdam"
via the new maxEVMVersionCheck() helper or the EVMVersion setting, with
counterparts exceeding the new limit of 235 where applicable.

Co-authored-by: Francisco Giordano <fg@frang.io>
All space-separated constraints in the `EVMVersion` setting have to be
satisfied for the test to run. This allows expressing version ranges,
e.g. `>homestead <=osaka` for tests whose expectations only hold before
"amsterdam" but which cannot run on the oldest versions either.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants