the cross-chain update mechanism of the SDLPoolSecondary can lead to a deadlock situation, where the updateInProgress flag remains indefinitely set to 1. This occurs when the update transaction on the primary chain or the callback transaction to the secondary chain fails. As a result, the system is unable to process new updates, effectively freezing the staking system in the secondary pool and leaving user actions in a state of suspension without a recovery mechanism in place.
When actions are queued on the secondary chain, the function performUpkeep in the SDLPoolCCIPControllerSecondary is tasked with sending these updates to the primary chain. This involves invoking the handleOutgoingUpdate function within the SDLPoolSecondary, and then send the crosschain updates to the primary chain :
in the handleOutgoingUpdate function it checks if an update is already in progress by examining the updateInProgress flag. If set to 1, the function will revert, preventing any further updates.If no update is in progress, handleOutgoingUpdate sets updateInProgress to 1 and prepares to send the number of new queued locks (numNewQueuedLocks) and the change in the reSDL supply (reSDLSupplyChange) to the primary chain:
in the primary chain the SDLPoolCCIPControllerPrimary receives the message. and verifies that the sender is the SDLPoolCCIPControllerSecondary in the src chain, then calls handleIncomingUpdates in the SDLPoolPrimary, which provides the mintStartIndex. This index is then communicated back to the secondary chain by the SDLPoolCCIPControllerPrimary in another crosschain transaction.
the issue occurs if the transaction on the primary chain reverts or the callback transaction that sends mintStartIndex from primary to secondary chain reverts for any reason (which high likely, for example miss passing the _extraArgs , not enough LINK tokens in SDLPoolCCIPControllerPrimary to pay fee for the callback ...ect). This event would severely disrupt this secondary pool functionality. In the event of a transaction revert, there is no recovery mechanism, and sending updates to the primary chain for new actions on the secondary chain becomes impossible because the ccipControllerSecondary is the sole contract authorized to send such transaction, but it can only do so when the updateInProgress flag is zero,and the updateInProgress flag only get reset to 0, when the udpated sended to the primary has returned the mintStartIndex to the function handleIncomingUpdate in the secondaryPool, which won't happend cause the transaction failed :
This results in a deadlock situation where the system is indefinitely stalled, unable to process any new updates. The updateInProgress flag remains perpetually set to 1 signaling that an update is still being processed and thus blocking the initiation of any subsequent updates.
This vulnerability stops all updates between the secondary and primary pools, leaving users' staked funds inaccessible and disrupting the staking service.
manual review
Introduce a fallback mechanism that resets the updateInProgress flag in the event of a transaction failure. This could involve a timeout function or a manual override by an authorized administrator to ensure that updates can resume and the system can recover from stalled states.
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.