Incorrect handling of pricefeed.decimals() #195
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
edited-by-warden
high quality report
This report is of especially high quality
resolved
Finding has been patched by sponsor (sponsor pls link to PR containing fix)
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-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/oracles/PegOracle.sol#L46-L83
https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/Controller.sol#L299-L300
Vulnerability details
Impact
Wrong maths for handling pricefeed decimals. This code will only work for pricefeeds of 8 decimals, any others give wrong/incorrect data. The maths used can be shown in three lines:
Line1: adds 4 decimals
Line2: adds (18 - d) decimals, (where d = pricefeed.decimals())
Line3: removes 6 decimals
Total: adds (16 - d) decimals
when d=8, the contract correctly returns an 8 decimal number. However, when d = 6, the function will return a 10 decimal number. This is further raised by (18-d = 12) decimals when checking for depeg event, leading to a 22 decimal number which is 4 orders of magnitude incorrect.
if d=18, (like usd-eth pricefeeds) contract fails / returns 0.
All chainlink contracts which give price in eth, operate with 18 decimals. So this can cripple the system if added later.
Proof of Concept
Running the test AssertTest.t.sol:testPegOracleMarketCreation and changing the line on
https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/test/AssertTest.t.sol#L30
to
gives this output
returning an oracle value of 0. Simulating with a mock price feed of 6 decimals gives results 4 orders of magnitude off.
Tools Used
Foundry, vs-code
Recommended Mitigation Steps
Since only the price ratio is calculated, there is no point in increasing the decimal by (18-d) in the second line. Proposed solution:
This returns results in d decimals, no matter the value of d.
The text was updated successfully, but these errors were encountered: