Skip to content

Use transient storage in Outbox and Bridge - #260

Draft
gvladika wants to merge 38 commits into
chore/solc-0.8.30from
t-store
Draft

gvladika wants to merge 38 commits into
chore/solc-0.8.30from
t-store

Conversation

@gvladika

@gvladika gvladika commented Oct 11, 2024 •

Copy link
Copy Markdown
Contributor

Stacked on #479.

  • Keep the Outbox's L2-to-L1 context and the Bridge's active outbox in transient storage instead of storage. That saves about 10k gas per withdrawal today, and 16–25k after Glamsterdam raises storage write costs (EIP-8038).
  • Leave the old storage slots in place as deprecated __context and __activeOutbox, so the storage layout doesn't change. They keep their current placeholder values, and nothing reads them.
  • Remove postUpgradeInit from the Outbox and IOutbox. The old slots are left as they are rather than wiped, so the upgrade needs no init call.
  • setOutbox now rejects address(0) instead of the all-ff address, because 0 is what activeOutbox now holds when no outbox is active.
  • Bump solhint to ^5.0.5, the first release that can parse transient.

Part of BLK-430

@cla-bot cla-bot Bot added the s label Oct 11, 2024
Comment thread src/bridge/AbsBridge.sol Fixed
@gvladika
gvladika changed the base branch from develop to bold-merge October 16, 2024 09:44
Comment thread src/bridge/AbsBridge.sol Resolved
Comment thread src/bridge/AbsBridge.sol Resolved
Comment thread src/bridge/AbsBridge.sol Resolved
Comment thread src/bridge/AbsOutbox.sol Resolved
Comment thread src/bridge/AbsBridge.sol Resolved
Comment thread src/bridge/AbsBridge.sol Fixed
Comment thread src/bridge/AbsOutbox.sol Outdated
Comment on lines +49 to +51
/// @dev Due to how arb governance works, it is not possible to wipe out the content of these
/// 4 storage slots during the upgrade. So after deprecation values in these slots will
/// stay "dirty" with default values, but slots will not be used or accessible in any way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let's remove these, keeping them dirty is simply a design choice

@gzeoneth
gzeoneth self-requested a review October 31, 2024 13:21
Base automatically changed from bold-merge to develop December 11, 2024 11:21
@yahgwai
yahgwai removed their request for review July 27, 2026 08:50
Conflict resolutions:
- hardhat.config.ts, audit-ci.jsonc, slither.db.json: take chore/solc-0.8.30.
  Its 0.8.30/cancun config replaces this branch's 0.8.28 bump, and the audit
  allowlist follows the current lockfile.
- contract-tests.yml: use the repo's install-foundry action; keep this branch's
  format check, solhint and coverage steps disabled.
- AbsBridge.setOutbox: keep the new formatting with this branch's address(0) check.
- ERC20Outbox.t.sol: keep the _happyExecTx helper and add this branch's
  zeroed-context asserts to it.
- test/storage, test/signatures: regenerated.
Re-accepts three findings already triaged on develop or this branch, which reappeared under new line numbers: Bridge._executeLowLevelCall arbitrary-send-eth, and the AbsOutbox.executeTransactionImpl reentrancy and AbsBridge.activeOutbox write-after-write from the transient save/restore. Triaged with slither-analyzer 0.11.4, the version CI installs.
@yahgwai yahgwai added the audit-before-merge Not yet audited. Keep off develop until it is, so it never delays a release. label Nov 6, 2026
@yahgwai
yahgwai changed the base branch from develop to chore/solc-0.8.30 November 6, 2026 14:16
Bump solhint to ^5.0.5, the first release whose parser accepts `transient`, and rename the disabled custom-errors rule to its new name, gas-custom-errors. Format BridgeTester with Foundry 1.8.3, the version CI pins.
@yahgwai yahgwai removed the s label Nov 6, 2026
Re-accepts the AbsOutbox.executeTransactionImpl reentrancy and AbsBridge.activeOutbox write-after-write findings at their new line numbers. Triaged with slither-analyzer 0.11.4.
Recording the bridge's active outbox in setVersion broke the e2e retryable test, which calls it from an aliased L1 address rather than the bridge. Move the recording into setVersionAndRecordOutbox and use that in the Foundry bridge test.
Transient variables get slots by declaration order, so an upgrade that runs mid-withdrawal needs that order kept, just like storage. The snapshot is only appended for contracts that have transient variables, so today only the bridge and outbox snapshots change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

audit-before-merge Not yet audited. Keep off develop until it is, so it never delays a release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants