stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: medium
Invalid

Users on secondary chains will not be able to withdraw until the next rewards distribution

Summary

The execution flow of actions on secondary chains differs from that on the primary chain. When a user performs any action that will alter their effective reSDL balance the action will be queued instead of taking effect immediately. To process this queue, either the keeper or anyone else should invoke SDLPoolCCIPControllerSecondary.performUpkeep. For this to occur, the shouldUpdate value must be set to true. The issue, or perhaps the arguable feature, arises because shouldUpdate is set only within the code that handles the receiving of rewards from the primary chain. Consequently, users cannot perform any actions, including withdrawals, until the next rewards distribution.

Vulnerability Details

The execution flow on secondary chains unfolds as follows:

  1. The user calls a desired function on the secondary chain (withdraw, for example). This action is recorded in SDLPoolSecondary.queuedLockUpdates, and SDLPoolSecondary.updateNeeded is set to true.

  2. The keeper invokes RewardsInitiator.updateRewards to distribute rewards. Importantly, this function is permissioned, verifying that msg.sender is included in the whitelistCallers.

  3. If there are some rewards for the secondary chain (though they might be zero due to rounding, especially if the chain's supply is relatively low), SDLPoolCCIPControllerPrimary sends these rewards to the secondary chain.

  4. After the rewards distribution, SDLPoolCCIPControllerSecondary sets shouldUpdate to true.

  5. The keeper or any other entity calls SDLPoolCCIPControllerSecondary.performUpkeep. This call sends an update to the primary chain, and only after receiving the response the user can execute the withdrawal.

The issue with this setup is that users cannot withdraw their funds in a permissionless manner. If there are no new rewards or the whitelisted keeper is inactive, the users' funds become essentially inaccessible. While I understand that this is by design, I still believe it would be beneficial to incorporate a permissionless "escape hatch" to allow users to withdraw without any additional trusted parties.

Impact

Users cannot withdraw their funds until the next reward distribution.

Tools Used

Manual Review

Recommendations

Consider adding a new function to SDLPoolCCIPControllerSecondary that allows the initiation of an update if SDLPoolSecondary.shouldUpdate() is true. However, impose a fee on the caller of this function to deter a potential draining of the contract's funds. As far as I can tell, this modification doesn't compromise the protocol but enhances it from the users' perspective.

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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