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.
The execution flow on secondary chains unfolds as follows:
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.
The keeper invokes RewardsInitiator.updateRewards
to distribute rewards. Importantly, this function is permissioned, verifying that msg.sender
is included in the whitelistCallers
.
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.
After the rewards distribution, SDLPoolCCIPControllerSecondary
sets shouldUpdate
to true.
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.
Users cannot withdraw their funds until the next reward distribution.
Manual Review
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.
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.