Platform: Code4rena
Start Date: 03/05/2022
Pot Size: $50,000 USDC
Total HM: 4
Participants: 46
Period: 5 days
Judge: gzeon
Total Solo HM: 2
Id: 117
League: ETH
Rank: 10/46
Findings: 3
Award: $439.72
๐ Selected for report: 0
๐ Solo Findings: 0
Deprecated Chainlink oracle API. API might stop working. Prices could be outdated. Protocol might need to be redeployed or false prices might lead to users losing funds.
The contracts use Chainlinkโs deprecated API latestAnswer()
. Such functions might suddenly stop working if Chainlink stopped supporting deprecated APIs.
Additionally, one cannot check if the returned price is fresh. The price might by stale (old historical price).
Manual review
Use the latestRoundData()
function to get the price instead.
Add checks on the return data with proper revert messages if the price is stale or the round is uncomplete, for example:
(uint80 roundID, int256 price, , uint256 timeStamp, uint80 answeredInRound) = oracle.latestRoundData(); require(answeredInRound >= roundID, "..."); require(timeStamp != 0, "...");
#0 - bunkerfinance-dev
2022-05-09T18:19:43Z
Duplicate of #1
๐ Selected for report: BowTiedWardens
Also found by: 0x1337, 0x1f8b, 0x4non, 0xDjango, David_, Funen, GimelSec, IllIllI, Picodes, TerrierLover, WatchPug, bobi, cryptphi, csanuragjain, delfin454000, dirk_y, ellahi, fatherOfBlocks, hyh, ilan, jayjonah8, kebabsec, leastwood, oyc_109, robee, samruna, simon135, sorrynotsorry, throttle
93.5794 USDC - $93.58
Consider emitting an event
New admin is not checked against 0 value.
Consider checking if new admin address is not 0
๐ Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xkatana, Cityscape, Fitraldys, Funen, GimelSec, IllIllI, MaratCerby, Picodes, TerrierLover, Tomio, delfin454000, ellahi, fatherOfBlocks, hansfriese, ilan, joestakey, oyc_109, rfa, robee, samruna, simon135, slywaters, throttle
47.5594 USDC - $47.56
redeemAllowed()
could be simplified.Function redeemAllowed()
could be simplified.
function redeemAllowed(address cAsset, address redeemer, uint redeemTokens) external returns (uint) { uint allowed = redeemAllowedInternal(cAsset, redeemer, redeemTokens); if (allowed != uint(Error.NO_ERROR)) { return allowed; } // Keep the flywheel moving // updateCompSupplyIndex(cAsset); // distributeSupplierComp(cAsset, redeemer); return uint(Error.NO_ERROR); }
could be rewritten to
function redeemAllowed(address cAsset, address redeemer, uint redeemTokens) external returns (uint) { return redeemAllowedInternal(cAsset, redeemer, redeemTokens); }
Consider rewriting
This:
for (uint256 i = 0; i < len; i++) { ... }
can be optimized to
for (uint256 i; i < len;) { ... unchecked { ++i }; }
Consider rewriting