The setVestingPeriod
may relock previously released assets
Description
The setVestingPeriod
function in the StakedUSDf contract allows changing the vestingPeriod
duration, but it does not verify whether the current unvested amount is zero.
As a result, if the vesting period is increased, a portion of previously released assets may become locked again.
function _setVestingPeriod(uint32 newPeriod) internal {
uint32 oldVestingPeriod = vestingPeriod;
require(newPeriod <= MAX_VESTING_PERIOD, DurationExceedsMax());
require(oldVestingPeriod != newPeriod, DurationNotChanged());
require(newPeriod > 0 || cooldownDuration > 0, ExpectedCooldownOn()); // if period is 0, cooldown must be on
vestingPeriod = newPeriod;
emit VestingPeriodUpdated(oldVestingPeriod, newPeriod);
}
function getUnvestedAmount() public view returns (uint256) {
uint256 timeSinceLastDistribution = uint40(block.timestamp) - lastDistributionTimestamp;
if (timeSinceLastDistribution >= vestingPeriod) {
return 0;
}
uint256 deltaT;
unchecked {
deltaT = (vestingPeriod - timeSinceLastDistribution);
}
return (deltaT * vestingAmount) / vestingPeriod;
}
Impact
If assets were already withdrawn before the vesting period increase, the totalAssets
calculation will be incorrect, leading to potential discrepancies in the system's accounting. However, since this function is controlled by a DEFAULT_ADMIN_ROLE
and is intended to be used only for reducing the vesting duration, the impact of this issue is classified as Informational.
Recommendations
Implement a verification check in the setVestingPeriod
function to ensure that the current unvested amount is zero before allowing changes to the vesting period.
Remediation
This issue has been acknowledged by Falcon, and a fix was implemented in commit 4a5ce0b9↗.