fix(pwq): blacklist gate on PriorityWithdrawalQueue claim#441
Merged
0xpanicError merged 2 commits intoMay 28, 2026
Merged
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 2a96fcf. Configure here.
Addresses H-3 from the multi-lens audit of PR #385. PriorityWithdrawalQueue.claimWithdraw was callable on behalf of any `request.user`, including a sanctioned address that became blacklisted between request finalization and claim — proceeds would flow to the blacklisted user via a non-blacklisted accomplice. Add blacklister as an immutable, wire it through the constructor with a zero-check, and call `blacklister.nonBlacklisted(request.user)` at the top of `_claimWithdraw` so both `claimWithdraw` and `batchClaimWithdraw` fail-closed on sanctioned recipients. Cancel path is already covered transitively via eETH's own `nonBlacklisted` on transfer. H-2 — bid-revenue treasury setter was acked rather than implemented. Storage-collision risk with the pre-deprecation DEPRECATED_admin slot makes the safe fix non-trivial; deferred. Test/script call-site updates thread the new PWQ blacklister arg.
2a96fcf to
662d851
Compare
|
I dont see the rationale to have blacklister on priority queue as it is already whitelist gated. |
0xpanicError
approved these changes
May 28, 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
Addresses H-3 from the multi-lens audit of PR #385.
PriorityWithdrawalQueue._claimWithdrawnow gates onblacklister.nonBlacklisted(request.user). Previously anyone could claim on behalf ofrequest.user, including when that user became blacklisted between finalization and claim — proceeds would flow to a sanctioned address via a non-blacklisted accomplice. BothclaimWithdrawandbatchClaimWithdrawnow fail-closed.Disposition of other audit findings
executeTaskspermissionless) — intended, documented in the existing source comments.DEPRECATED_adminslot on the deployed proxy: post-upgrade, the newtreasurystorage slot reads as the old admin EOA (non-zero), so the defensiveaddress(0)revert doesn't fire and bid revenue would silently leak. A correct fix requires a one-shot reinitializer batched into the upgradeupgradeToAndCall, which expands scope materially. Deferring to a follow-up.invalidateRequestreverts on finalized requests (WRN.sol:352) andEtherFiAdmin._validateWithdrawalssums only valid requests for the lock amount. The "double-lock" path isn't reachable.ethAmountLockedForWithdrawal >= request.amountOfEEthat claim entry). Cosmetic change, no real underflow path.Changes by file
src/withdrawals/PriorityWithdrawalQueue.solIBlacklister public immutable blacklister; thread through constructor with zero-check; addblacklister.nonBlacklisted(request.user)at top of_claimWithdraw.test/TestSetup.sol,test/PriorityWithdrawalQueue.t.sol,test/integration-tests/*,test/fork-tests/UpgradeStorageIntegrity.t.solscript/upgrades/priority-queue/transactionsPriorityQueue.s.soladdress(0)for blacklister in PWQ constructor; operator substitutes real address pre-deploy for bytecode-match verification.Test plan
forge buildclean (only pre-existing lint warnings)forge test --match-path test/PriorityWithdrawalQueue.t.solagainst a mainnet fork — requiresMAINNET_RPC_URLtest_claimWithdraw_revertsForBlacklistedRequestUser(PWQ) — flagged by testing reviewer as priority follow-uptest_batchClaimWithdraw_revertsEntireBatchOnBlacklistedUser(PWQ) — pin batch failure semanticsNote
Medium Risk
Touches withdrawal payout and whitelist access with a new immutable constructor arg; mis-deployed blacklister address would brick the implementation, but behavior aligns with existing Blacklister usage elsewhere in the stack.
Overview
PriorityWithdrawalQueue now wires in
IBlacklisteras a constructor immutable (non-zero required) and uses it for sanctions gating.Whitelist flows (
onlyWhitelisted) callblacklister.nonBlacklisted(msg.sender)so a compromised VIP can be blocked by blacklist before ops removes whitelist.Claims (
_claimWithdraw, including batch) callblacklister.nonBlacklisted(request.user)so a third party cannot claim finalized ETH to a user who was blacklisted after fulfillment.Constructor arity changes are reflected across tests, fork/integration upgrades, and the priority-queue upgrade script (bytecode verification still uses a placeholder
address(0)for blacklister until ops substitutes the deployed address).Reviewed by Cursor Bugbot for commit 6a5dd7a. Bugbot is set up for automated code reviews on this repo. Configure here.