Platform: Code4rena
Start Date: 12/08/2022
Pot Size: $50,000 USDC
Total HM: 15
Participants: 120
Period: 5 days
Judge: Justin Goro
Total Solo HM: 6
Id: 153
League: ETH
Rank: 80/120
Findings: 1
Award: $46.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0x1f8b
Also found by: 0x52, 0xA5DF, 0xDjango, 0xNazgul, 0xNineDec, 0xSmartContract, 0xmatt, 0xsolstars, Aymen0909, Bnke0x0, CertoraInc, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, EthLedger, Funen, IllIllI, JC, Junnon, Lambda, LeoS, MiloTruck, Noah3o6, PaludoX0, ReyAdmirado, Rohan16, RoiEvenHaim, Rolezn, SaharAP, Sm4rty, SooYa, The_GUILD, TomJ, Waze, Yiko, _Adam, __141345__, a12jmx, ak1, asutorufos, auditor0517, ayeslick, ballx, beelzebufo, berndartmueller, bin2chen, brgltd, c3phas, cRat1st0s, cccz, cryptonue, cryptphi, d3e4, delfin454000, dipp, djxploit, durianSausage, dy, erictee, fatherOfBlocks, gogo, gzeon, hyh, ignacio, kyteg, ladboy233, medikko, mics, minhquanym, oyc_109, pfapostol, rbserver, reassor, ret2basic, robee, sach1r0, simon135, sryysryy, tabish, yac, yash90, zzzitron
46.0118 USDC - $46.01
Using too recent Solidity versions could be potentially dangerous, in addition when the optimizer is enabled. This project introduces both, floating pragma to ^0.8.15 and enabled optimizer with 200 runs.
In past there were discovered several bugs (https://docs.soliditylang.org/en/v0.8.16/bugs.html) and also in the latest releases (https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug/).
Use more battle-tested version, at least few months old while preserving wanted features and disable the optimizer if it's possible.
renounceOwnership
featureOpenzeppelin's Ownable contract introduces the renounceOwnership
function that allows to renounce the owner of the contract. However, if it is not intended to be used in future, it will be safer to disable this function
These contracts will be more solid without this feature:
These contracts are on consideration:
Override the renounceOwnership
function to disable this feature.
Openzeppelin's Ownable contract introduces only one-phase ownership that transfers the ownership directly. This could be potentially dangerous when some mistake happens, due to that, it is better to use two-phase transfer of the ownership.
Implement nomination of the owner that can be later claimed on all places where is expected that the owner will be EOA.
In FraxlendPairDeployer there are several addresses with escalated privileges (like CIRCUIT_BREAKER_ADDRESS
for the globalPause
function) that are missing setter functions. Adjustment of their values will need to redeploy the contract.
// Admin contracts address public CIRCUIT_BREAKER_ADDRESS; address public COMPTROLLER_ADDRESS; address public TIME_LOCK_ADDRESS;
Since their values are the only ones assigned in the constructor (except FRAXLEND_WHITELIST_ADDRESS
) it could be useful to add setters. If not, make them immutable.
block.timestamp
The struct ExchangeRateInfo
is using uint32
for the preserving value of the block.timestamp
while other part of the protocols are using the safer value uint64
.
struct ExchangeRateInfo { uint32 lastTimestamp; uint224 exchangeRate; // collateral:asset ratio. i.e. how much collateral to buy 1e18 asset }
Consider a lifetime of the project if the gas optimization is worthy, since in 2106 it can overflow and cause the protocol unusable.
In the _addInterest
function on line 468, there is hardcoded number for divison, instead of using proper constant for precision
// Calculate interest accrued _interestEarned = (_deltaTime * _totalBorrow.amount * _currentRateInfo.ratePerSec) / 1e18;
Second occurence is in the FraxlendPair
contract.
function assetsPerShare() external view returns (uint256 _assetsPerUnitShare) { _assetsPerUnitShare = totalAsset.toAmount(1e18, false); }
There should be probably decimals()
instead.
Replace the hardcoded numbers with a proper constant to prevent decimal errors in future updates.
Although it is claimed that the configuration of deployment is left completely up to deployer and the protocol is aware of it, it would be better to include some basic checks, where is already known that they will lead to a unusable protocol.
More precisely, zero-address checks for _asset
and _collateral
in FraxlendPairCore
.
Add zero-address checks for _asset
and _collateral
in FraxlendPairCore
constructor.