Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Incorrect vault group update causes FundFlowController::claimPeriodActive to always return false, impacting token withdrawal functionality

Summary

The function FundFlowController::claimPeriodActive will always return false due to an error in the calculation of the curUnbondedVaultGroup variable. This results in an inability to properly manage vault group claims during the unbonding process.

Vulnerability Details

The FundFlowController plays a major role of the protocol as it unbounds vault groups one at a time, preventing them from being emptied simultaneously, and allowing the protocol to always have one group vault unbounded to allow withdraws. This logic is implemented in the claimPeriodActive function, which is supposed to return true when a vault group is between the start and the end of the claim period.

However, this function will always return false because the variable timeOfLastUpdateByGroup is not updated correctly in updateVaultGroups. The actual group updated at the end of this function is the previous group, as the variable curUnbondedGroup is set to the current vault group. This means the timeOfLastUpdateByGroup of the next group (the one that is in the process of unbonding) isn't updated.
As a result, the variable timeOfLastUpdateByGroup[curUnbondedVaultGroup] in claimPeriodActive will return a previous, incorrect value of a past update.

If claimPeriodActive would be called right after updateVaultGroups, the assertion block.timestamp > claimPeriodEnd would already be true, proving the claimPeriodActive function can never return true.

Impact

While claimPeriodActive is a view function, it is called in :

This logic flaw leads to the following situations : VaultControllerStrategy::withdraw will always revert, because !fundFlowController.claimPeriodActive() will always be true, and VaultControllerStrategy::getMinDeposits will always return totalDeposits, preventing the unbounding of tokens from the vaults.

PoC

The following hardhat test can be added in the file test/linkStaking/fund-flow-controller.test.ts and run using npx hardhat test --grep "fundflowcontroller claimperiodactive is never true"

it('fundflowcontroller claimperiodactive is never true', async () => {
const { fundFlowController } = await loadFixture(deployFixture)
// Note: Your hardhat test may fail. If so, try to uncomment the two following lines.
// await time.increase(await fundFlowController.unbondingPeriod())
// await time.increase(await fundFlowController.unbondingPeriod())
// This for loops proves that the `claimPeriodActive` is NEVER true.
// Looping once is enough to prove the bug, but you can still edit it to loop more,
// and see the test still pass anyway
for (let i = 0; i < 1; i++) {
// We update the vault groups
await fundFlowController.updateVaultGroups()
// Wait for `unbondingPeriod` to pass
await time.increase(await fundFlowController.unbondingPeriod())
// `claimPeriodActive` should be true but is false
assert.isFalse(await fundFlowController.claimPeriodActive())
}
// This happens because the actual block.timestamp is already
// higher than the `claimPeriodEnd`
// Adding the following console.log in `FundFlowController::claimPeriodActive`
// before the return statement will always return true
// console.log(block.timestamp > claimPeriodEnd);
})

Tools Used

Manual review.

Recommendations

To resolve this issue, update the timeOfLastUpdateByGroup variable in FundFlowController::updateVaultGroups so that it correctly tracks the next unbonded group :

- timeOfLastUpdateByGroup[curUnbondedGroup] = uint64(block.timestamp);
+ timeOfLastUpdateByGroup[nextUnbondedGroup] = uint64(block.timestamp);
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[INVALID]FundFlowController::claimPeriodActive to always return false, impacting token withdrawal functionality

Appeal created

strapontin Submitter
about 1 year ago
strapontin Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[INVALID]FundFlowController::claimPeriodActive to always return false, impacting token withdrawal functionality

Support

FAQs

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