Open code423n4 opened 3 years ago
For this to happen, poolUpkeep
would have to revert; the only way for this to happen (as pointed out by the warden) is if the update interval hasn't passed, OR for there to be an underlying bug in the contracts. However, as per the checkUpkeepSinglePool call on line 94, the function would never get to the try-catch if the update interval hasn't passed; thus, the only want for this to happen is there to be an underlying bug in the contracts that makes it revert, as we don't explicitly or implicitly allow any other way for it to. If the warden can prove there to be a way for poolUpkeep
to revert (not withstanding the update interval not passing as that's already checked for), we would consider this to be a valid issue but otherwise we disagree with the severity as it requires there to be/needs to be paired wtith another bug in the contracts.
We will act on the suggestion nonetheless thought -- in case there's a regression and uncommit
does have the ability to revert, thank you for that.
I agree with the sponsor in that "in the case of a revert" doesn't really sound convincing for a high severity finding.
I appreciate the finding in that it does seem like it would be best to update the storage value only on success
I will downgrade to Low Severity, and think about this one over the weekend as there may be more
Handle
WatchPug
Vulnerability details
https://github.com/tracer-protocol/perpetual-pools-contracts/blob/646360b0549962352fe0c3f5b214ff8b5f73ba51/contracts/implementation/PoolKeeper.sol#L90-L118
In the current implementation, when
pool.poolUpkeep()
fails (possibly because "Update interval hasn't passed"), the price change will not impact the long & short balances.However, at L104
executionPrice[_pool]
was updated tolatestPrice
already, so that it will be used asoldPrice
in upcoming updates.This means the current price change in this period is ignored, but the storage gets updated anyway, making the protocol believe it's the price change is been settled properly.
As a result, when the price goes up, the attacker can take advantage of this, and make the long positions have not benefited and the short positions have not suffered, vice versa.
Proof of Concept
Given:
executionPrice[_pool]
is now100
;latestPrice
rise to200
within theupdateInterval
;The attacker can:
performUpkeepSinglePool()
:executionPrice[_pool]
will get updated to200
, whileshortBalance
andlongBalance
of theLeveragedPool
remain unchanged;100
afterintervalPassed
, the attacker can callperformUpkeepSinglePool()
again:The protocol now believes that the price of the token has fallen relative to the last updated price, therefore it will increase the balance of the short positions, and decrease the balance of the long positions.
Recommendation
Change to: