The protocol supports standard ERC20 stake tokens and explicitly excludes only fee-on-transfer and rebasing behavior. Blacklist-capable ERC20 tokens such as USDC are not fee-on-transfer or rebasing tokens, but they can revert transfers to or from sanctioned addresses.
All staker exit paths transfer funds only to msg.sender. There is no withdrawTo(address), claimSurvivedTo(address), or claimExpiredTo(address) variant that lets a staker route their entitlement to a non-blacklisted recipient. If a staker is blacklisted after depositing, their withdrawal or claim reverts at the token transfer and their principal remains recorded in eligibleStake.
The same no-alternate-recipient root also applies to the good-faith CORRUPTED bounty path. claimAttackerBounty() requires msg.sender == attacker and pays the bounty to attacker directly. If the named good-faith attacker is blacklisted by the stake token, the bounty transfer reverts and the attacker cannot claim to a clean recipient during the claim window.
The withdrawal path in ConfidencePool.sol::withdraw transfers only to msg.sender, so a token-level recipient blacklist makes the exit revert instead of letting the staker route the same entitlement to another address.
The SURVIVED claim path in ConfidencePool.sol::claimSurvived has the same recipient restriction: the staker's principal plus bonus payout is sent only to msg.sender.
The good-faith bounty path in ConfidencePool.sol::claimAttackerBounty also pays only the named attacker. The caller must be attacker, and the transfer recipient is the same attacker address, so a blacklisted attacker cannot claim to a clean recipient.
The sweep reserve in ConfidencePool.sol::sweepUnclaimedBonus keeps reserving for the unclaimable staker because the reverted claim leaves that staker's principal in totalEligibleStake.
Because the reverted staker claim leaves eligibleStake, totalEligibleStake, and hasClaimed unchanged, the staker cannot exit and the pool continues reserving the stuck principal. With an observed risk window, the sweep reserve can also continue reserving the unclaimed bonus portion.
Because the reverted bounty claim rolls back bountyClaimed, corruptedReserve, and claimsStarted, the named attacker also cannot claim any part of the bounty to another address. The only eventual movement is the post-deadline sweepUnclaimedCorrupted() path to recoveryAddress, which does not help the entitled good-faith attacker.
Likelihood: Low
The factory owner must allowlist a blacklist-capable ERC20 token that is otherwise standard and not fee-on-transfer or rebasing (e.g. USDC/USDT).
A staker address or named good-faith attacker must then be blacklisted independently of the pool's own logic while still having a pool entitlement.
Impact: Low
The blacklisted staker cannot withdraw or claim to an alternate address, so their principal and any bonus entitlement remain stuck in the pool.
A blacklisted good-faith attacker cannot receive the bounty or route it to another recipient, so their entitlement remains in the pool until it can be swept to recoveryAddress after the claim window.
The stuck position remains counted in totalEligibleStake, which prevents normal bonus sweeping from releasing the reserved amount.
The PoC file included with this report is:
To run it in a fresh contest checkout:
Copy BlacklistTokenStakerLockupPoC.t.sol into the repository's test/ directory.
Run:
Expected result:
The PoC demonstrates:
A blacklist-capable ERC20, two stakers, a SURVIVED outcome, one staker blacklisted before claim, and the blacklisted staker's principal plus bonus remaining reserved in the pool after their claim reverts.
A good-faith CORRUPTED outcome where the named attacker is blacklisted before claiming and cannot route the bounty to an alternate recipient.
Inline PoC source (BlacklistTokenStakerLockupPoC.t.sol):
Add alternate-recipient exit functions so the entitlement owner can route withdrawals, claims, and good-faith bounties to a non-blacklisted address.
Apply the same pattern to withdraw(), claimExpired(), and claimAttackerBounty().
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.