Skip to content

Base V2 pools: MAX_WITHDRAW_DELAY_TIME 1 day -> 30 days, and a deployer mode for prebuilt pool implementations - #359

Merged
rbcp18 merged 9 commits into
developfrom
claude/sweet-pasteur-wkpcf3
Sep 27, 2026
Merged

rbcp18 merged 9 commits into
developfrom
claude/sweet-pasteur-wkpcf3

Conversation

@rbcp18

@rbcp18 rbcp18 commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Records the Base V2 pool implementation upgrade that is now live, and the chain-deployer mode that shipped it.

What's live on Base

  • Beacon 0x7848585b…dc83 now runs 0xf5d3E8aCf964d4b95ec87B2E849A5Cee3e62239a (verified on Basescan), in place of 0xd177f4b8…1a7f.
  • The only source change from the previous implementation is MAX_WITHDRAW_DELAY_TIME = 86400 → 2592000, on the e30dbeb5 source that was deployed, compiled with solc 0.8.11 at 200 runs.
  • The USDC/TIBBIR pool 0x13cD7cF4…097b has withdrawDelayTimeSeconds set to 1209600 (14 days).
  • The upgrade went through the protocol timelock. The implementation is initialized and owned by the protocol Safe.

Changes

  • packages/contracts/upgrades/base_pool_v2_max_withdraw_delay_30d/ holds the reviewed build:

    • the source, ABI and bytecode;
    • the standard JSON input for verification;
    • the deploy data and a manifest;
    • a README recording the transactions.

    Its .sol sits outside contracts/, so neither hardhat nor forge compiles it.

  • helpers/tasks/deploy-pool-v2-impl.ts is a new hardhat task that deploys a prebuilt implementation from upgrades/<dir>.

    • Before sending anything, it checks that the live implementation's code equals the reviewed build, except for the immutable slots and the metadata hash.
    • After deploying, it checks that the new code equals the live code, except for the one allowed immutable change.
    • Then it initializes the implementation, transfers its ownership to the protocol Safe, verifies it, and writes the timelock schedule and execute calls as Safe Transaction Builder batches.
  • scripts/deploy-chain.sh gets a new DEPLOY_POOL_V2_IMPL=<dir> mode, plus _DRY_RUN and _ADDRESS. It never pushes artifacts.

  • deployments/base/upgrades/… holds the receipt and the Safe batches from the run.

Breaking changes

None.

  • No file under contracts/ changes. The setWithdrawDelayTime commit and its revert cancel out.
  • Existing deploy-chain.sh modes are untouched. The new block only runs when DEPLOY_POOL_V2_IMPL is set.
  • The task file loads under hardhat help and passes tsc.

Testing

  • An end-to-end run on a local hardhat chain used a real OZ TimelockController, beacon and proxy.
    • The task deployed, locked and verified the implementation.
    • The Safe batches executed, and the pool then accepted a 30-day delay that it had rejected with WD before the upgrade.
    • A build with one instruction byte changed was refused.
  • A dry run and a live run on Base both went through the chain-deployer Railway service.

Known issue, not addressed here

The share lock can be bypassed. _afterTokenTransfer stamps only the sender's timestamp, so shares moved to a fresh wallet can be redeemed straight away. Fixing that needs a separate contract change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG


Generated by Claude Code

Protocol-owner-only setter for withdrawDelayTimeSeconds.

Note: with this change the V2 runtime bytecode is 24,756 bytes
(solc 0.8.24, optimizer 200, paris), above the EIP-170 24,576-byte
limit, so it is not deployable as-is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
Only change vs the deployed implementation 0xd177f4b8... (source commit
e30dbeb, solc 0.8.11, optimizer 200) is MAX_WITHDRAW_DELAY_TIME
86400 -> 2592000. Includes source, ABI/bytecode, deploy tx data,
constructor args and standard JSON input for verification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
…cap upgrade

Hardhat task that deploys the prebuilt implementation in upgrades/<dir>,
checks what landed, locks it via initialize + transferOwnership, verifies
the source, and writes Safe Transaction Builder batches for the timelock
schedule/execute of the beacon upgrade plus follow-up calls.

Not wired into scripts/deploy-chain.sh; nothing invokes it yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
Runs the deploy-pool-v2-impl task for upgrades/<dir>: deploys the
prebuilt implementation, locks it, verifies it and prints the Safe
batches for the timelock schedule/execute. DEPLOY_POOL_V2_IMPL_DRY_RUN
checks the chain and sends nothing. Never pushes artifacts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
Before sending anything, compare the live implementation's runtime code
with the reviewed build outside immutable slots and the metadata hash,
and report whether the metadata equals the unmodified source's. After
deploying, compare new against live the same way and require the only
differing immutable values to be manifest.immutableChange (86400 ->
2592000). Adds immutableRanges and originalRuntimeMetadata to the
artifact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
Implementation 0xf5d3E8aCf964d4b95ec87B2E849A5Cee3e62239a, deployed,
initialized, owned by the protocol Safe and verified by the chain
deployer. Batch 1 schedules the beacon upgrade on the timelock; batch 2,
7200s later, executes it and sets the USDC pool's withdraw delay to
2591999s. Calldata checked against the deploy log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
Step 2 went through the protocol timelock, not a direct upgradeTo, and
the pool was set to 14 days rather than the 2591999s in the batch.
Records the transactions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrHWEwddMYFYkieyTuKjsG
@rbcp18
rbcp18 merged commit 257f087 into develop Sep 27, 2026
2 checks passed
@rbcp18
rbcp18 deleted the claude/sweet-pasteur-wkpcf3 branch September 27, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants