Fee can be minted multiple times
Description
The harvest
function is called in the deposit
, withdraw
, mint
, and redeem
functions. In these functions, the totalUnderlyingStamp
and lastStamp
are updated at the end of the function.
The harvest
function can also be called externally for minting a fee to the feeRecipient
. The computeHarvestFee
function returns the fee amount based on the time passed since the lastStamp
and the amount of totalUnderlyingStamp
. However, the lastStamp
and totalUnderlyingStamp
are not updated in the harvest
function. So the harvest
function can be called multiple times to mint the fee multiple times.
function harvest() public returns (uint256) { // @audit harvest does not update the lastStamp and totalUnderlyingStamp.
// so it can mint the newShares multiple times.
uint256 fee = computeHarvestFee();
uint256 newShares = (totalSupply() + VIRTUAL_SHARES) * fee / (MAX_BPS - fee);
console.log("newShares", newShares);
if (newShares != 0) {
_mint(config.feeRecipient, newShares);
}
return newShares;
}
Impact
An attacker can mint the fee multiple times, inflating the total supply of shares. This abnormal increase affects the exchange rate of shares and assets.
Recommendations
Update both lastStamp
and totalUnderlyingStamp
within the harvest
function to prevent repeated minting of the same fee.
Remediation
This issue has been acknowledged by StakeKit, and a fix was implemented in commit e01ab9b9↗.