Commit Graph
75 Commits
Author SHA1 Message Date
xermicusandLJ 68e8b167f5 NY: bugfix dead callvalue analysis (#589)
- Remove the buggy `fn find_value_uses()`
- The logic flips from default-skip to default-keep

Closes #588

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Co-authored-by: LJ <81748770+elle-j@users.noreply.github.com>
2026-08-14 23:22:56 +02:00
xermicusandClaude Opus 4.8 16c255bf18 Fix/ny unaligned store fmp oog (#566)
Bug found by @jubnzv:

`--newyork`: an unaligned `mstore` corrupting the free-memory-pointer
word let a later store through the corrupted pointer silently succeed
where EVM runs out of gas.

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:13:59 +02:00
xermicusandClaude Opus 4.8 61b7ab8521 Fix/ny fn native fmp oog (#567)
Bug found by @jubnzv:

`--newyork`: a full-width value stored to the free-memory-pointer slot
(e.g. a function parameter `>= 2^64`) was narrowed to 64 bits, inserting
a checked truncation that consumed all gas.

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 17:41:05 +02:00
xermicusandClaude Opus 4.8 e2e6514953 Fix/ny msize dse expansion (#565)
Bug found by @jubnzv:

`--newyork`: dead-store elimination could drop a store whose memory
expansion an intervening `msize()` observes, so `msize()` read a stale
(unexpanded) value.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:31:01 +02:00
9adfd9db24 Fix/ny dynamic calldatacopy fmp (#564)
Bug found by @jubnzv:

`--newyork`: a `calldatacopy`/`codecopy`/`returndatacopy` to a dynamic
destination that could overwrite the free-memory-pointer word truncated
a subsequent `mload(0x40)` to `0`.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Agent <agent@local>
2026-07-08 15:44:11 +02:00
xermicusandClaude Opus 4.8 da547e9dd9 Fix/ny dse overlapping load (#563)
Another bug found by @jubnzv:

`--newyork`: dead-store elimination could drop a store that a later
overlapping unaligned `mload` reads, returning zeroed memory instead of
the stored bytes.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 09:12:30 +02:00
xermicusandClaude Opus 4.8 c18d29b861 Fix/ny unaligned mload native byteorder (#562)
Another bug found by @jubnzv:

`--newyork`: an unaligned full-word `mload`/`mstore` overlapping a word
kept native (little-endian) by the heap optimization returned
byte-swapped bytes.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 19:38:21 +02:00
xermicus 9b177f6400 Fix NY codegen wth folded guard + inlined for-loop (#561)
Fixes a ICE wth folded guard in inlined for-loop in NY.

Closes #560

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
2026-07-06 12:37:55 +02:00
xermicus 541955d31b add integration test for i32 operand overflow in PVM linker const fold (#552)
Closes #551

---------

Signed-off-by: xermicus <cyrill@parity.io>
2026-06-25 18:01:54 +02:00
98d818f958 The new Yul optimizer toolkit (#519)
This PR introduces powerful code size optimizations. This is achieved
with an additional IR layer in between Yul and LLVM IR. It works quite
well (see below for a comparison) because it captures optimization gains
that neither solc nor LLVM can realize.

The feature is gated behind `--newyork` or a corresponding standard JSON
input setting and **off by default**.

### How it works

We implemented an SSA IR modelled after or inspired by the [MLIR SCF
dialect](https://mlir.llvm.org/docs/Dialects/SCFDialect/). Yul is
translated into this IR and the IR implements mainly the following
optimizations:

- **Type narrowing**: narrows 256-bit values to I1..I160 where provable
(bidirectional + interprocedural), so LLVM emits native 32/64-bit ops
instead
    of software 256-bit arithmetic.
- **FMP range proof**: exposes the `mload(0x40) < heap_size` bound to
LLVM
IPSCCP, eliminating trailing overflow checks on FMP-derived offsets.
Single
    largest code-size contributor.
- **Heap analysis**: skips big-endian byte-swaps where native
little-endian
    layout is safe.
  - **mem_opt / keccak fusion+folding**, **compound outlining** (mapping
sload/sstore), **guard narrowing**, **inlining** tuned for PolkaVM, and
    **exact + fuzzy function dedup**.

### Results
The optimizations implemented with the newyork IR bring substantial code
size improvements.
  - Integration contracts: approximately **-20% to -50%** code size.
  - OpenZeppelin Wizard corpus: around **-47%** code size.

This table shows the code size improvements on various OpenZeppelin ERC
implementations, taken from their [contracts
wizard](https://wizard.openzeppelin.com/), with almost all features
enabled.

| Contract | Default: (bytes) | With `--newyork`: (bytes) | Reduction |
|---|---:|---:|---:|
| erc1155 | 59,206 | 30,649 | -48.2% |
| erc20 | 81,697 | 42,893 | -47.5% |
| erc721 | 92,052 | 49,423 | -46.3% |
| oz_gov | 141,861 | 81,159 | -42.8% |
| oz_rwa | 77,274 | 37,975 | -50.9% |
| oz_simple_erc20 | 29,950 | 16,554 | -44.7% |
| oz_stable | 82,117 | 39,032 | -52.5% |
| **Total** | **564,157** | **297,685** | **-47.2%** |

We believe this to be a reasonably representative dataset and conclude
that the newyork IR achieves drastic code size reductions on real world
dApp implementations.

### Methodology, security and runtime performance

Since the main contributors to these improvements are the FMP range
proofs and the type narrowing, we don't expect big runtime performance
regressions (it may even benefit runtime performance in some cases).

The PR also includes docs
(`book/src/developer_guide/newyork_{optimizer,ir}.md`) and many new
integration tests, including regression tests for known FMP soundness
traps.

The PR was authored collaboratively and reviewed extensively by the
`revive` maintainers, as well as Claude Opus, Claude Fable, Qwen,
Minimax and Deepseek LLMs, over a span of many months.

The `newyork` compiler pipeline introduces no new regressions over our
integration and differential test suites (containing over 30000 test
cases). This was achieved by careful manual reviews and many LLM bughunt
loops. Additionally, a final security review by Anthropic's Fable 5 LLM
found no remaining soundness issues. Nonetheless, like any brand new
software, please consider this an experimental feature upon release.

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: neo <me@90f9.org>
Co-authored-by: LJ <81748770+elle-j@users.noreply.github.com>
2026-06-17 12:35:16 +02:00
xermicus ae8033130b Fix __ulongrem stdlib edge case (#531)
The implementation is off-by-one.

---------

Signed-off-by: xermicus <cyrill@parity.io>
2026-05-28 17:25:23 +02:00
xermicus 40e97d11eb Fix optimization specific SREM edge case (#527)
Existing test coverage didn't catch a signed remainder overflow
semantics edge case behavior where at least one the operators is being
constant folded by LLVM instead of solc. This PR fixes the SREM
translation bug and adds missing test coverage for division ops with
constants.

Closes #524

---------

Signed-off-by: xermicus <cyrill@parity.io>
2026-05-28 09:01:41 +02:00
xermicus ee869cdd18 Support solc v0.8.35 (#512)
- Support solc v0.8.35
- The new `erc7201` is comptime (already translated to a constant in
Yul)

Didn't spot any relevant breakage or addition in the release notes so
should be no-brainer.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2026-05-01 20:14:36 +02:00
xermicus 95ae938ddf Add missing 63/64 rule documentation and a test (#462)
- Prominently point out the important differences of the `pallet-revive`
runtime.
- Add a test case illustrating the problem.

See also: https://github.com/paritytech/contract-issues/issues/257

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2026-01-27 19:43:14 +01:00
LJ c601377c2d Add integration test for deleting struct (#459)
Differentially tests the behavior of deleting a struct with a member
that do not occupy the full 32-byte slot. From [this
issue](https://github.com/paritytech/contract-issues/issues/118) it was
unclear whether the `delete` was expected to reset only the bytes
occupied or the entire slot. The current behavior of resetting the
entire slot is expected.
2026-01-20 14:34:27 +01:00
xermicus 289af875db remove superfluous byte swap in linkersymbol builtin translation (#455)
- Remove the superfluous byte swap in the `linkersymbol` builtin
translation.
- Support testing the `linkersymbol` builtin translation in the runner
specs.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2026-01-15 12:43:46 +01:00
xermicus be6f734cfc Use the EVM call gas syscall variants (#436)
- Emit the `call_evm` and `delegate_call_evm` syscalls for contract
calls.
- The call gas is no longer ignored.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-12-18 17:01:24 +01:00
xermicus 25ee4eef5a dedicated safe integer truncation integration test (#435)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-12-17 10:25:41 +01:00
xermicus 9446132608 Emit consume_all_gas in invalid and bounds checks (#433)
Closes #374

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-12-16 10:04:51 +01:00
xermicus 11f82c8488 Support solc v0.8.31 (#430)
- Support for solc v0.8.31.
- Support for the `clz` Yul builtin.

---------

Signed-off-by: xermicus <cyrill@parity.io>
2025-12-05 15:25:13 +01:00
xermicus 45ceab7dc7 Additional bounds check in sbrk (#428)
Close #356

Signed-off-by: xermicus <cyrill@parity.io>
2025-12-03 16:00:19 +01:00
xermicus a1090cfa5a revive-yul: fix the code block exit (#414)
This PR fixes the missing `STOP` instruction at the end of `code`
blocks.

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
2025-11-17 18:47:58 +01:00
xermicus 70037e1136 initial SELFDESTRUCT support (#400)
Note:
- The unstable interface in `v2509.0.0` of `polkadot-sdk` is required.
- The differential test fails against EVM in `v2509.0.0` of
`polkadot-sdk`.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-11-03 15:04:04 +01:00
xermicus c0cdde5a5a llvm-context: fix off-by-one in SDIV overflow semantics (#398)
- Fix the wrong predicate (the negative side in 2s complement has one
more bit)
- Increase test coverage

Signed-off-by: xermicus <cyrill@parity.io>
2025-10-31 14:07:01 +01:00
xermicus f46bea6a96 llvm-context: do not trap zero length OOB heap access (#389)
Fixes https://github.com/paritytech/contract-issues/issues/120

---------

Signed-off-by: xermicus <cyrill@parity.io>
2025-10-15 22:39:42 +02:00
xermicus 6858cb9a61 mark internal functions linker private (#381)
Prevents unused functions in the emitted ELF object. Drive-by add a
missing test case (which misses a relocation under `-Oz` when all
internal functions are marked as private).

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-09-29 17:55:29 +02:00
xermicus 8754d802fa llvm-context: bugfix PHI values in SAR builtin translation (#345)
Closes #344

Signed-off-by: xermicus <cyrill@parity.io>
2025-06-14 15:12:03 +02:00
xermicus dab29bc89b bugfix missing byte swap for the create2 salt value (#272)
Found in https://github.com/paritytech/contract-issues/issues/45, thanks
@albertov19 and @sekisamu

---------

Signed-off-by: xermicus <cyrill@parity.io>
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-04-03 15:20:22 +02:00
xermicus 4a9b651235 Support solc v0.8.29 (#261)
No observable changes w.r.t. YUL compilation.
- Mark solc v0.8.29 as the latest supported version
- Add integration test for solc v0.8.29 specific feature
- Use the latest version on CI
- Drive-by fix linter complaints and a two types in the CI yaml files

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
2025-03-18 13:01:15 +01:00
xermicus 93788e72e9 integration: additional mcopy test (#245)
Closes #237

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-02-27 11:39:31 +01:00
xermicus 296a226d0b integration: add delegate call corner case test (#243)
Closes #235

---------

Signed-off-by: xermicus <cyrill@parity.io>
2025-02-27 11:10:00 +01:00
xermicus 84deb3a29d integration: add function return type test (#244)
Closes #236
2025-02-27 10:37:37 +01:00
xermicus cb268850a9 llvm-context: remove the linear memory pointer indirection (#211) 2025-02-13 13:21:43 +01:00
xermicus 374563bbe5 integration: add function pointer integration test (#205)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-02-10 18:50:12 +01:00
xermicus 60fc09f787 llvm-context: disable call re-entrancy for send and transfer (#196) 2025-02-06 16:49:50 +01:00
xermicus de3e7bf253 integration: add create2 test case with duplicate salt (#188)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-02-04 14:04:14 +01:00
xermicus bfda465c32 remove support for legacy evm assembly (#186) 2025-02-03 14:13:43 +01:00
xermicus 1a8a7926e9 implement the coinbase opcode (#179)
Signed-off-by: xermicus <cyrill@parity.io>
2025-01-29 15:24:45 +01:00
Cyrill Leutwiler d8752ec6b5 the basefee opcode (#142)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-19 18:59:10 +01:00
Cyrill Leutwiler 22070a824d the gas limit opcode (#139)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-18 20:31:42 +01:00
Cyrill Leutwiler 14a598e840 implement the gas opcode (#136) 2024-12-18 17:19:32 +01:00
Cyrill Leutwiler f0d9d44dce Implement the gasprice opcode (#127) 2024-11-29 17:14:27 +01:00
Ermal Kaleci 01b5ed5ba3 Implement delegate_call (#80) 2024-11-23 18:05:21 +01:00
Cyrill Leutwiler 6a120463c2 implement the blockhash opcode (#114) 2024-11-15 13:11:04 +01:00
Cyrill Leutwiler 43d2ef3ce9 implement the code size opcodes (#107) 2024-10-31 11:46:47 +01:00
Cyrill Leutwiler 5b3b90db83 support the origin opcode (#103)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-10-29 18:40:25 +01:00
Ermal Kaleci ee83d28a51 Implement extcodehash (#77) 2024-10-21 10:13:50 +02:00
Ermal Kaleci d9842b5427 Fix implementation for balance_of (#79)
The balance_of syscall is now available in pallet-revive.
- Fix balance_of implementation to use correct runtime api
- Add build_address_argument_store helper to be used for address arguments
2024-10-12 12:35:10 +02:00
Cyrill Leutwiler 705d1d7866 run signed_remainder test in differential mode (#75) 2024-10-10 19:26:04 +02:00
Cyrill Leutwiler d5d419cefc implement immutable variables codegen (#70) 2024-10-10 13:33:00 +02:00