Platform: Code4rena
Start Date: 14/09/2022
Pot Size: $50,000 USDC
Total HM: 25
Participants: 110
Period: 5 days
Judge: hickuphh3
Total Solo HM: 9
Id: 162
League: ETH
Rank: 36/110
Findings: 2
Award: $163.57
🌟 Selected for report: 0
🚀 Solo Findings: 0
155.5605 USDC - $155.56
Precision error due to division before multiplication.
amount.divWadDown(idFinalTVL[id]).mulDivDown( idClaimTVL[id], 1 ether )
Formula is (amount / idFinalTVL[id]) * idClaimTVL[id]
If amount = 1, idFinalTVL[id] = 1000, idClaimTVL[id] = 1000 result will be (1 / 1000) * 1000 = 0 * 1000 = 0
But if (amount * idClaimTVL[id]) / idFinalTVL[id]
result will be (1 * 1000) / 1000 = 1000 / 1000 = 1
Change formula to (amount * idClaimTVL[id]) / idFinalTVL[id]
to multiply before division
#0 - HickupHH3
2022-10-29T09:16:54Z
8.0071 USDC - $8.01
https://github.com/code-423n4/2022-09-y2k-finance/blob/ac3e86f07bc2f1f51148d2265cc897e8b494adf7/src/oracles/PegOracle.sol#L57-L63 https://github.com/code-423n4/2022-09-y2k-finance/blob/ac3e86f07bc2f1f51148d2265cc897e8b494adf7/src/oracles/PegOracle.sol#L89-L106
latestRoundData price1 is not checking for stale price. It bypassed the check as it used a low-level call to priceFeed1.latestRoundData instead of calling getOracle1_Price, which has been prevented from returning a stale price.
( uint80 roundID1, int256 price1, uint256 startedAt1, uint256 timeStamp1, uint80 answeredInRound1 ) = priceFeed1.latestRoundData(); int256 price2 = getOracle2_Price();
price1 is using low-level call to latestRoundData in contrast to price2 using calls to getOracle2_Price which has a stale prevention
/* solhint-disbable-next-line func-name-mixedcase */ /** @notice Lookup first oracle price * @return price Current first oracle price */ function getOracle1_Price() public view returns (int256 price) { ( uint80 roundID1, int256 price1, , uint256 timeStamp1, uint80 answeredInRound1 ) = priceFeed1.latestRoundData(); require(price1 > 0, "Chainlink price <= 0"); require( answeredInRound1 >= roundID1, "RoundID from Oracle is outdated!" ); require(timeStamp1 != 0, "Timestamp == 0 !"); return price1; } /* solhint-disbable-next-line func-name-mixedcase */ /** @notice Lookup second oracle price * @return price Current second oracle price */ function getOracle2_Price() public view returns (int256 price) { ( uint80 roundID2, int256 price2, , uint256 timeStamp2, uint80 answeredInRound2 ) = priceFeed2.latestRoundData(); require(price2 > 0, "Chainlink price <= 0"); require( answeredInRound2 >= roundID2, "RoundID from Oracle is outdated!" ); require(timeStamp2 != 0, "Timestamp == 0 !"); return price2; }
#0 - HickupHH3
2022-10-15T07:05:10Z
dup of #61