Liquid Staking

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

Unstake Reverts Due to Missing Inactivity Check in VaultControllerStrategy's Withdrawal Process

Summary

The VaultControllerStrategy::withdraw attempts to unstake tokens from the Chainlink staking contract without verifying if the contract is inactive, which is a requirement for the unstake operation to succeed.

Vulnerability Details

The unstake() function in the Chainlink contract has a whenInactive modifier. The current implementation does not check the staking contract's status before attempting to unstake, leading to potential reverts.

VaultControllerStrategy::Withdraw Checks if the vault can withdraw (deposits exist, claim period active, vault not removed).
Calls vault.withdraw(amount) to initiate withdrawal.

function withdraw(uint256 _amount, bytes calldata _data) external {
//...
135 if (deposits != 0 && vault.claimPeriodActive() && !vault.isRemoved()) {
136 if (toWithdraw > deposits) {
137 vault.withdraw(deposits);
138 unbondedRemaining -= deposits;
139 toWithdraw -= deposits;
140 } else if (deposits - toWithdraw > 0 && deposits - toWithdraw < minDeposits) {
141 // cannot leave a vault with less than minimum deposits
142 vault.withdraw(deposits);
143 unbondedRemaining -= deposits;
144 break;
145 } else {
146 vault.withdraw(toWithdraw);
147 unbondedRemaining -= toWithdraw;
148 break;
149 }
150 }
}

VaultControllerStrategy::Withdraw Calls vault.withdraw(amount) to initiate withdrawal.
vault.withdraw(deposits); goes to Vault contract

vault.withdraw(deposits); goes to Vault contract
[contracts/linkStaking/base/Vault.sol]
76 function withdraw(uint256 _amount) external virtual onlyVaultController {
77 stakeController.unstake(_amount); // @audit - Chainlink contract has modifier "WhenInactive" so this can revert
78 token.safeTransfer(vaultController, _amount);
79 }

unstake() only works if the contract is inactive (whenInactive modifier).
Transfers unstaked tokens to the caller.

Impact

Reverts: If the Chainlink staking contract is active, any attempt to unstake will fail, causing a transaction revert.

Operational Risk: This can disrupt the withdrawal process, impacting the strategy's ability to manage funds effectively.

Tools Used

Manual Review

Recommendations

Implement a check to ensure the Chainlink staking contract is inactive before calling the unstake function.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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