Skip to content

refactor: declare escrow and ERC-20 events once - #346

Draft
zguesmi wants to merge 5 commits into
mainfrom
pr/a-dedupe-events
Draft

refactor: declare escrow and ERC-20 events once#346
zguesmi wants to merge 5 commits into
mainfrom
pr/a-dedupe-events

Conversation

@zguesmi

@zguesmi zguesmi commented Aug 31, 2026

Copy link
Copy Markdown
Member

Non-breaking cleanup found while reviewing #345.

1. Dead network entry

scripts/verify.ts still listed 'dev-token' in skippedNetworks. That network was deleted from hardhat.config.ts in a6775e4, so the entry was dead.

2. Duplicate event declarations

Transfer, Reward, Seize, Lock and Unlock were each declared twice: in contracts/interfaces/IexecERC20.sol and in contracts/abstract/IexecEscrow.sol. It compiled only because the two declaration sites are inherited by disjoint contract sets (IexecEscrow -> IexecPoco1Facet, IexecPoco2Facet, IexecPocoBoostFacet; IexecERC20 -> IexecEscrowTokenFacet and the IexecInterfaceToken aggregate). Any contract that ended up inheriting both would have failed to compile.

Each event is now declared exactly once, in an interface (events are ABI, so an interface is the right home):

Interface Events Inherited by
IexecERC20Events Transfer IexecERC20, abstract IexecEscrow
IexecEscrowEvents Lock, Unlock, Reward, Seize abstract IexecEscrow, IexecEscrowToken

Approval stays in IexecERC20: only the ERC-20 entry points emit it.

3. Escrow events leave the ERC-20 surface

Reward, Seize, Lock and Unlock are escrow-accounting events. They are emitted from contracts/abstract/IexecEscrow.sol, contracts/facets/IexecPoco2Facet.sol and contracts/facets/IexecPocoBoostFacet.sol, never by ERC-20 code, so they no longer sit on IexecERC20.

They stay reachable from IexecInterfaceToken through the IexecEscrowToken interface, so the aggregate's flattened ABI does not change.

Two design notes

  • Why Transfer moved to its own interface instead of staying inline in IexecERC20. The abstract IexecEscrow also emits Transfer, and it cannot inherit IexecERC20 (that interface has functions, and the concrete PoCo facets would then have to implement transfer, approve, ...). A shared events-only parent is the only way to declare the event once and keep it in every current ABI. Approval is deliberately not in that parent: adding it there would add an Approval event to the three PoCo facet ABIs, which do not have one today.
  • IexecEscrowToken now declares four events it never emits. IexecEscrowTokenFacet carries Lock, Unlock, Reward and Seize in its published ABI today, inherited by accident from IexecERC20. Keeping the facet's ABI byte-identical requires preserving that. Dropping them from the escrow facet's ABI is a separate, breaking change.

Verification

ABI gate: abis/ snapshotted before the change, rebuilt, diffed. Only the two per-interface files that were supposed to move changed, plus the two new interface files:

M abis/contracts/interfaces/IexecERC20.json          events: [Approval, Lock, Reward, Seize, Transfer, Unlock] -> [Approval, Transfer]
M abis/contracts/interfaces/IexecEscrowToken.json    events: [] -> [Lock, Reward, Seize, Unlock]
+ abis/contracts/interfaces/IexecERC20Events.json
+ abis/contracts/interfaces/IexecEscrowEvents.json
(+ the mirrored human-readable-abis entries)

Every contract-level ABI is byte-identical: IexecEscrowTokenFacet, IexecInterfaceToken, IexecPoco1Facet, IexecPoco2Facet, IexecPocoBoostFacet and all other facets. ABI entries are sorted by solc, so the reshuffled inheritance does not move them.

topic0 is unchanged. No event signature was edited, only the declaration site, so every topic0 stays where it is and the subgraph is unaffected.

Runtime bytecode of IexecEscrowTokenFacet is identical up to the trailing CBOR metadata hash (first difference at byte offset 6566 of 6609, inside the metadata blob). The change is source-only; only the metadata hash moves.

Gate Result
npm run build compiled 119 Solidity files successfully
npm run check-storage-layout pass, no output
npm run doc regenerated, docs/solidity/index.md committed
npm run sol-to-uml regenerated, 3 SVGs committed
npx tsc --noEmit the 6 known pre-existing errors, no new ones
npm test 514 passing, 6 pending, 0 failing (same as base)
npm run format:check All matched files use Prettier code style

zguesmi and others added 4 commits August 31, 2026 11:27
Remove the duplicate declarations of `Transfer`, `Reward`, `Seize`, `Lock`
and `Unlock`. They were declared twice, in `IexecERC20` and in the abstract
`IexecEscrow`, and only compiled because the two declaration sites were
inherited by disjoint sets of contracts.

Each event is now declared exactly once, in an interface:

-   `IexecERC20Events` holds `Transfer`, which both the ERC-20 surface and the
    escrow accounting emit. `IexecERC20` and the abstract `IexecEscrow`
    inherit it.
-   `IexecEscrowEvents` holds `Reward`, `Seize`, `Lock` and `Unlock`. These are
    escrow-accounting events emitted by the PoCo facets, never by ERC-20 code,
    so they leave the ERC-20 surface. The abstract `IexecEscrow` and the
    `IexecEscrowToken` interface inherit it, which keeps them reachable from
    `IexecInterfaceToken`.

`Approval` stays in `IexecERC20`: only the ERC-20 entry points emit it.

Also remove the dead `'dev-token'` entry from `skippedNetworks` in
`scripts/verify.ts`; that network was deleted from `hardhat.config.ts`.

No ABI change: event signatures are untouched, so topic0 does not move, and
the contract-level ABIs are byte-identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.54%. Comparing base (862c1f7) to head (2243d23).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #346   +/-   ##
=======================================
  Coverage   99.54%   99.54%           
=======================================
  Files          31       31           
  Lines        1095     1095           
  Branches      212      223   +11     
=======================================
  Hits         1090     1090           
  Misses          5        5           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zguesmi
zguesmi marked this pull request as draft August 31, 2026 10:41
Base automatically changed from refactor/merge-token-contracts to main August 31, 2026 10:43
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.

1 participant