distribute() won't update epoch[tigAsset] when totalShares[tigAsset]==0 which can cause later created bond for this tigAsset to have wrong mint epoch #436
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
M-16
selected for report
This submission will be included/highlighted in the audit report
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-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/BondNFT.sol#L206-L228
https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/BondNFT.sol#L48-L86
Vulnerability details
Impact
Function
BondNFT.createLock()
creates a bond and it sets bond's mint epoch asepoch[asset]
, functionLock.lock()
first callsclaimGovFees()
which callsBondNFT.distribute()
for all assets and updates theepoch[assets]
for all assets. so during normal bond creation the value ofepoch[asset]
would be updated and bond would be created fromtoday
epoch totoday+period
epoch. but iftotalShares[tigAsset] == 0
for an asset, thendistribute()
won't updateepoch[asset]
for that asset andepoch[asset]
will be some old epoch(will be the start time where asset is added or the time wheretotalShares[_tigAsset] != 0
). This would makecreateLock()
to set very wrong value for bond's mint epoch whentotalShares[tigAsset] == 0
.This would happen for the first bond that has been created for that asset always and it will happen again if for some period
totalShares[asset]
become 0, then the next bond would have wrong mint epoch. orsetAllowedAsset(asset, false)
has been called for that asset.Proof of Concept
This is
distribute()
code in BondNFT contract:As you can see when
totalShares[_tigAsset] == 0
then the value ofepoch[_tigAsset]
won't get updated to the today. and there is no other logics in the code to updateepoch[tigAsset]
. so whentotalShares[_tigAsset] == 0
then the value of theepoch[tigAsset]
would be out dated. this would happen when asset is recently added to the BondNFT assets or when in some time there is no bond left.When this condition happens and a user call
Lock.lock()
to create a bond thelock()
function would callclaimGovFees()
to update rewards in BondNFT but because for that asset the value of totalShares are 0 so for that assetepoch[]
won't get updated and in theBondNFT.createLock()
the wrong value would set as bond't mint epoch.This is
Lock.lock()
code:And this is
BondNFT.createLock()
code:if a bond get wrong value for mint epoch it would have wrong value for expire epoch and user would get a lot of share by lock for small time. for example this scenario:
epoch[asset1]
is out dated and it shows 30 days ago epoch. (allowedAsset[asset1]
was false so locking was not possible and then is set as true after 30 days)totalShare[asset1]
was 0 sodistribute()
function won't udpateepoch[asset1]
andepoch[asset1]
would show 30 days ago.Lock.lock(asset1)
. code would callBondNFT.createLock()
and would create a bond for attacker which epoch start time is 30 days ago and epoch expire time is 2 days later and attacker receives shares for 32 days.asset1
.so attacker was able to create lock for long time and get shares and rewards based on that but attacker can release lock after short time.
Tools Used
VIM
Recommended Mitigation Steps
update
epoch[asset]
indistribute()
function even whentotalShares[_tigAsset]
is equal to 0. only the division by zero and fund transfer should be prevented when totalShare is zero andepoch[asset]
index should be updated.The text was updated successfully, but these errors were encountered: