Open sherlock-admin opened 7 months ago
1 comment(s) were left on this issue during the judging contest.
takarez commented:
invalid: the coolDown is in place for withdrawing tokens not for reStaking 'em
Fix LGTM
The protocol team fixed this issue in PR/commit https://github.com/covalenthq/cqt-staking/pull/125/commits/e7ab9ab7eb89f47669dfc0c4ef175f6ca074328b.
The Lead Senior Watson signed off on the fix.
PUSH0
high
No cooldown in
recoverUnstaking()
, opens up several possible attacks by abusing this functionality.Summary
The function
recoverUnstaking()
allows a user to recover any of their unstaking to the same validator.However, the function has no cooldown, i.e. a user can unstake and restake to the same validator at any time they prefer.
We describe several attack vectors that may arise from this issue.
Vulnerability Detail
When a user unstakes, they must wait for a cooldown of 28 days (180 days if validator) before being able to withdraw. The user also has the choice to revert the action, and re-stake said amount back to the same validator by calling
recoverUnstaking()
.However, the function
recoverUnstaking()
has no cooldowns. In other words, a user can re-stake as many times as they like, at any time they prefer, without being subject to the unstaking cooldown.This opens up several possible attack vectors by abusing the lack of cooldown of this functionality.
Next section we describe some of the possible attack vectors.
Denying delegators for any validators
An attacker with a large enough capital can do the following to deny a target validator from getting delegated stakings:
staked * maxCapMultiplier
, but immediately unstake.recoverUnstaking()
, re-staking their max stake.The impact is that a validator can be denied from getting delegators.
Stealing of rewards
This attack vector builds upon a separate issue we have submitted, about unfair distribution of rewards for mid-epoch stakers.
An attacker can perform the following, while greatly de-risking themselves from staking.
rewardValidators()
with the intent of front-running.rewardValidators()
calls, unfairly taking a share of the rewards.The attacker benefits from the following:
Impact
recoverUnstaking()
can be abused, opens up several possible attack vectors, with varying impacts (shown above).Code Snippet
https://github.com/sherlock-audit/2023-11-covalent/blob/main/cqt-staking/contracts/OperationalStaking.sol#L542
Tool used
Manual Review
Recommendation
Implement a cooldown for
recoverUnstaking()
. A short cooldown (e.g. a few days) is sufficient.