refactor: deprecate deposit & V0 paths in MembershipManager (strict deletion-only)#427
Merged
0xpanicError merged 2 commits intoMay 26, 2026
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6f2c5ec. Configure here.
…eletion-only)
After the one-shot V0 → V1 batch migration on mainnet (279 NFTs / ~186 ETH;
verified by full 10k-id sweep, all `tokenDeposits[id].amounts == 0`), the V0
storage + V0->V1 migration code + entire deposit/mint/top-up surface in
MembershipManager became unreachable from any live NFT. We're closing the
contract to new deposits anyway, so this PR removes that code.
Audit-scope guarantee
=====================
This is a strict deletion-only PR for source code:
src/MembershipManager.sol 306 deletions, 0 insertions
src/interfaces/IMembershipManager.sol 14 deletions, 0 insertions
src/MembershipNFT.sol 0 deletions, 0 insertions
src/interfaces/IMembershipNFT.sol 0 deletions, 0 insertions
src/archive/MembershipManagerV0.sol 0 deletions, 0 insertions
Every line of source code that remains is byte-identical to its
pre-trim form. No reorganization, no new comments, no new logic, no
behavior change in remaining code. The MembershipNFT contract is
untouched entirely.
Size impact (MembershipManager only):
before: 26,412 bytes (over EIP-170 limit)
after: 17,184 bytes (margin +7,392)
Functions removed from MembershipManager
========================================
External:
- wrapEthForEap
- wrapEth (uint256, uint256, address)
- wrapEth (uint256, uint256)
- topUpDepositWithEth
- migrateFromV0ToV1
- addNewTier, updateTier, setPoints, updatePointsParams
- setDepositAmountParams, setTopUpCooltimePeriod, setFeeAmounts,
setFanBoostThresholdEthAmount
Internal (had no remaining callers after the externals above were removed):
- _distributeStakingRewardsV0
- _claimStakingRewards
- _migrateFromV0ToV1
- _incrementTokenDeposit, _decrementTokenDeposit,
_incrementTierDeposit, _decrementTierDeposit
- _mintMembershipNFT, _deposit, _topUpDeposit, _wrapEth
- _incrementTokenVaultShareV1
- _setPoints, _feeAmountSanityCheck
Call-site removals in KEEP functions (single-line deletions only):
- rebase(): `_distributeStakingRewardsV0(...)`
- claim(): `_claimStakingRewards`, `_migrateFromV0ToV1`
- unwrapForEEthAndBurn(): same + the `// Claim ... before burn` comment
- requestWithdrawAndBurn(): same + the comment
Functions intentionally preserved
=================================
- canTopUp(...): kept because MembershipNFT.canTopUp() forwards to it.
Removing it would force a deletion in MembershipNFT, expanding scope.
Verification
============
- Full 10k-id mainnet sweep: 0 NFTs with `tokenDeposits.amounts > 0`,
1,761 alive V1 NFTs, 0 unexpected versions.
- test/MembershipDeprecationUpgradeFork.t.sol upgrades the live proxies
to the trimmed implementation and asserts real on-chain owners can:
* unwrapForEEthAndBurn on a migrated-V0 NFT (id 6251) → eETH received
* unwrapForEEthAndBurn on a born-V1 NFT (id 7500)
* requestWithdrawAndBurn on a born-V1 NFT (id 8500)
* partial requestWithdraw on a born-V1 NFT (id 9900)
* rebase(0 / +1 ETH / -1 ETH) — including the slashing branch
- test/V0MigrationFork.t.sol documents the batch-migration helper
(script/operations/v0-migration/) used to clear V0 holdouts.
Storage layout is preserved unchanged — the V0 mappings (tokenDeposits)
and array (tierDeposits) stay in the layout for a safe in-place UUPS
upgrade.
Test churn (also deletion-only):
test/Blacklist.t.sol: 22 deletions (3 deprecated blacklist tests).
6f2c5ec to
6b13418
Compare
0xpanicError
approved these changes
May 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Stacks on top of #420 (
pankaj/feat/security-upgrades). After the one-shot V0 → V1 batch migration on mainnet (279 NFTs / ~186 ETH; verified by full 10k-id sweep:tokenDeposits[id].amounts > 0count = 0), the V0 storage + V0→V1 migration code + the entire deposit/mint/top-up surface inMembershipManageris unreachable from any live NFT. We're also closing the contract to new deposits, so this PR removes that dead code.Audit-scope guarantee — strict deletion-only
src/MembershipManager.solsrc/interfaces/IMembershipManager.solsrc/MembershipNFT.solsrc/interfaces/IMembershipNFT.solsrc/archive/MembershipManagerV0.solEvery line of source code that remains is byte-identical to its pre-trim form. No reorganization, no new comments, no new logic, no behavior change in remaining code.
MembershipNFTis untouched entirely.Size impact (MembershipManager only)
Functions removed from
MembershipManagerExternal (entry points):
wrapEthForEap,wrapEth(×2),topUpDepositWithEthmigrateFromV0ToV1addNewTier,updateTier,setPoints,updatePointsParams,setDepositAmountParams,setTopUpCooltimePeriod,setFeeAmounts,setFanBoostThresholdEthAmountInternal (had no remaining callers after the externals above were removed):
_distributeStakingRewardsV0,_claimStakingRewards,_migrateFromV0ToV1_incrementTokenDeposit,_decrementTokenDeposit,_incrementTierDeposit,_decrementTierDeposit_mintMembershipNFT,_deposit,_topUpDeposit,_wrapEth_incrementTokenVaultShareV1,_setPoints,_feeAmountSanityCheckCall-site removals in KEEP functions (single-line deletions only — diff is purely lines preceded by
-):rebase():_distributeStakingRewardsV0(...)claim():_claimStakingRewards,_migrateFromV0ToV1unwrapForEEthAndBurn(): same + the// Claim ... before burncommentrequestWithdrawAndBurn(): same + the commentFunctions intentionally preserved
MembershipManager.canTopUp(...)— kept becauseMembershipNFT.canTopUp()forwards to it. Removing it would force a deletion inMembershipNFT, expanding audit scope. Pure view, no security implication.Storage layout
Preserved unchanged. The V0 mappings (
tokenDeposits) and array (tierDeposits) remain in the layout for a safe in-place UUPS upgrade — auto-generated getters return zeroed values.Verification
On-chain sweep
Full 10,000 ever-minted ID sweep against mainnet:
tokenDeposits[id].amounts > 0: 0version == 1(alive V1 NFTs): 1,761version == 0(burned slot or never minted): 8,239Fork test
test/MembershipDeprecationUpgradeFork.t.solforks mainnet, deploys the trimmed implementation, UUPS-upgrades the live MM proxy (owner() == UPGRADE_TIMELOCK), and exercises real on-chain fan-holder flows:unwrapForEEthAndBurn_migratedV00x8a28…A079unwrapForEEthAndBurn_bornV10x277f…7d44requestWithdrawAndBurn_bornV10xba32…315BrequestWithdraw_partial_bornV10x8B3f…13B7rebase_postTrim_allAccrualBranchesETHERFI_ADMINRun:
Migration artifacts
script/operations/v0-migration/ships the one-shot migrator that cleared the 279 V0 NFTs + the JSON ID list +test/V0MigrationFork.t.solfor re-verification at audit time.Test churn (also deletion-only)
test/Blacklist.t.sol: 22 lines deleted (3 blacklist tests exercising the removed deposit functions). No additions.Test plan
forge buildcleanforge test --match-contract MembershipDeprecationUpgradeForkTest --fork-url $MAINNET_RPC_URL— all 5 passupgradeToon the MM proxy; authorized byUPGRADE_TIMELOCK)cc @0xpanicError for review
Note
High Risk
Large deletion on a live UUPS proxy handling membership NFT balances and rebase; wrong ordering (trim before migration) or storage-layout mistakes could brick exits or rewards, though fork tests and preserved slots mitigate that.
Overview
This PR removes dead V0 and deposit surfaces from
MembershipManagerandIMembershipManagerafter the planned one-shot migration of the last 279 V0 membership NFTs (~186 ETH backing). It also adds operational artifacts (batch migrator, Foundry script, JSON ID lists, README) and mainnet fork tests to run and verify that migration and post-trim behavior.Contract trim: Deleted entry points include
wrapEth/wrapEthForEap,topUpDepositWithEth,migrateFromV0ToV1, tier/points/deposit/fee admin setters, and all V0 reward/migration/deposit internals.rebaseno longer calls V0 distribution;claim,unwrapForEEthAndBurn, andrequestWithdrawAndBurnno longer auto-claim V0 staking rewards or migrate before burn. V0 storage slots (tokenDeposits,tierDeposits) stay in the layout for a safe UUPS upgrade;canTopUpremains as a view forMembershipNFT.MembershipNFTis unchanged.Tests:
test/Blacklist.t.soldrops blacklist tests for removed deposit APIs. New fork tests upgrade to the trimmed impl and check unwrap, partial/full withdraw+burn, andrebase(0 / ± accrual); a separate fork test batch-migrates fromv0_ids_flat.jsonthen checks rebase and real-owner exits.Reviewed by Cursor Bugbot for commit 2694253. Bugbot is set up for automated code reviews on this repo. Configure here.