Users can claim extremely large rewards or lock rewards from LpGauge due to uninitialised poolLastUpdate
variable
#141
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/tokenomics/LpGauge.sol#L115-L119
https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/StakerVault.sol#L326-L328
Vulnerability details
Impact
A user can claim all of the available governance tokens or prevent any rewards from being claimed in
LpGauge.sol
if sufficient time is left between deploying the contract and initialising it in theStakerVault.sol
contract by callinginitalizeLPGauge()
OR if a newLPGauge
contract is deployed and added toStakerVault
usingprepareLPGauge
.Inside
LPGauge.sol
when calling_poolCheckPoint()
, thelastUpdated
variable is not initalised so defaults to a value of0
, therefore if the user has managed to stake tokens in theStakerVault
then the calculatedpoolStakedIntegral
will be very large (as block.timestamp is very large). Therefore a user can mint most current available governance tokens for themselves when they claim their rewards (or prevent any governance tokens from being claimed).Proof of Concept
initializeLpGauge()
, user A will stake 1 token withstakeFor()
thereby increasing_poolTotalStaked
by 1.As the
lpgauge
address is equal to the zero address,_userCheckPoint()
will not be called andpoolLastUpdate
will remain at 0._userCheckPoint()
and be allocated a very large number of shares. This works becausepoolLastUpdate
is 0 but the staked amount in the vault is larger than 0initializeLPGauge()
is called, the user can then callclaimRewards()
and receive a very large portion of tokens or ifpoolStakedIntegral
exceeds the mint limit set byMinter.sol
then no one else can claim governance tokens from the lpGauge.OR
5. A new LP Gauge contract is deployed and added to the vault using
prepareGauge()
.Follow steps 2 to 4.
Tools Used
Manual audit
Recommended Mitigation Steps
Initialise
poolLastUpdate
in the constructorThe text was updated successfully, but these errors were encountered: