FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: medium
Likelihood: medium

Immutable claim recipient permanently locks user funds when transfers to the original Staker become impossible

Author Revealed upon completion

Root + Impact

Description

The protocol allows eligible users to reclaim their principal and bonus by calling the appropriate claim function. Once a claim succeeds, the user's accounting is cleared and the transferred amount leaves the protocol.

But the issue is All payout paths are permanently bound to msg.sender . The protocol provides no mechanism to redirect payouts to another recipient if the designated address later becomes unable to receive ERC20 transfers due to blacklisting etc . As a result, when a token transfer fails,The claimant cannot recover the funds, while the protocol also cannot redirect or recover them because no alternate payout mechanism exists. The funds remain permanently locked inside the pool.

// Every user claim is hardcoded to msg.sender
// claimSurvived()
stakeToken.safeTransfer(msg.sender, payout);
// claimExpired()
stakeToken.safeTransfer(msg.sender, payout);
// withdraw()
stakeToken.safeTransfer(msg.sender, payout);
// claimAttackerBounty()
stakeToken.safeTransfer(attacker, payout);

Risk

Likelihood:

A claimant's payout address becomes unable to receive ERC20 transfers after staking due to blacklisting etc.

Impact:

  • Stakers can never withdraw their principal or Bonus.

  • owner also cannot sweep the fund so it will just locked in the contract forver.

  • neither user not owner can withdraw the tokens.

Proof of Concept

1. Alice stakes 100 USDC.
2. Pool Survives.
3. Before claiming, Alice's address becomes unable to receive token transfers
(e.g. Blacklisting).
4. Alice calls claimSurvived().
5. safeTransfer(msg.sender, payout) reverts.
6. No protocol function exists to redirect the payout to another address.
Result:
Alice's principal and bonus remain permanently locked inside the pool.

Recommended Mitigation

- stakeToken.safeTransfer(msg.sender, payout);
+ function claimTo(address recipient) external
+ function updateClaimRecipient(address newRecipient) external

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!