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: 20/120
Findings: 2
Award: $248.17
๐ 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
226.1154 USDC - $226.12
Severity: Low
approve is subject to a known front-running attack. It is deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead.
_assetContract.approve(_swapperAddress, _borrowAmount);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1103
_collateralContract.approve(_swapperAddress, _collateralToSwap);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1184
Consider using safeIncreaseAllowance() / safeDecreaseAllowance() instead.
Severity: Low
According to openzepplin's ERC721, the use of _mint is discouraged, use _safeMint whenever possible. https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#ERC721-_mint-address-uint256-
_mint(address(this), _feesShare);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L487
_mint(_receiver, _shares);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L570
Use _safeMint whenever possible instead of _mint
Severity: Low
Some tokens (like USDT L199) do not work when changing the allowance from an existing non-zero allowance value. They must first be approved by zero and then the actual allowance must be approved.
_assetContract.approve(_swapperAddress, _borrowAmount);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1103
_collateralContract.approve(_swapperAddress, _collateralToSwap);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1184
Approve with a zero amount first before setting the actual amount.
Severity: Low
function setTimeLock(address _newAddress) external onlyOwner {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L204
Consider adding zero-address checks in the mentioned codebase.
Severity: Low
The owner is the authorized user in the solidity contracts. Usually, an owner can be updated with transferOwnership function. However, the process is only completed with single transaction. If the address is updated incorrectly, an owner functionality will be lost forever.
_fraxlendPair.transferOwnership(COMPTROLLER_ADDRESS);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L262
Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.
Severity: Non-Critical
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairConstants.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/LinearInterestRate.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/SafeERC20.sol#L2
Found usage of floating pragmas ^0.8.15 of Solidity https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/VaultAccount.sol#L2
Severity: Non-Critical
If the variable needs to be different based on which class it comes from, a view/pure function should be used instead.
uint256 _LTV_PRECISION,
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L160
Severity: Non-Critical
_assetsPerUnitShare = totalAsset.toAmount(1e18, false);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L105
uint256 _price = uint256(1e36);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L522
bytes memory _firstHalf = BytesLib.slice(_creationCode, 0, 13000);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L171
_pairAddress := create2(0, add(bytecode, 32), mload(bytecode), salt)
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L226
uint256 _deltaUtilization = ((MIN_UTIL - _utilization) * 1e18) / MIN_UTIL;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L69
Severity: Non-Critical
Each event should use three indexed fields if there are three or more fields. In addition, each event should have at least one indexed fields to allow easier filtering of logs.
event SetTimeLock(address _oldAddress, address _newAddress);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L200
event WithdrawFees(uint128 _shares, address _recipient, uint256 _amountToTransfer);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L228
event SetSwapper(address _swapper, bool _approval);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L268
event AddInterest( uint256 _interestEarned, uint256 _rate, uint256 _deltaTime, uint256 _feesAmount, uint256 _feesShare );
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L376
event UpdateRate(uint256 _ratePerSec, uint256 _deltaTime, uint256 _utilizationRate, uint256 _newRatePerSec);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L389
event BorrowAsset( address indexed _borrower, address indexed _receiver, uint256 _borrowAmount, uint256 _sharesAdded );
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L696
event AddCollateral(address indexed _sender, address indexed _borrower, uint256 _collateralAmount);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L760
event RepayAsset(address indexed _sender, address indexed _borrower, uint256 _amountToRepay, uint256 _shares);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L846
event Liquidate( address indexed _borrower, uint256 _collateralForLiquidator, uint256 _sharesToLiquidate, uint256 _amountLiquidatorToRepay, uint256 _sharesToAdjust, uint256 _amountToAdjust );
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L897
event LeveragedPosition( address indexed _borrower, address _swapperAddress, uint256 _borrowAmount, uint256 _borrowShares, uint256 _initialCollateralAmount, uint256 _amountCollateralOut );
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1045
event RepayAssetWithCollateral( address indexed _borrower, address _swapperAddress, uint256 _collateralToSwap, uint256 _amountAssetOut, uint256 _sharesRepaid );
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1137
Severity: Non-Critical
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
function setCreationCode(
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L170
OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5
Severity: Non-Critical
contract FraxlendPair is FraxlendPairCore
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L41
contract FraxlendPairDeployer is Ownable
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L44
contract FraxlendWhitelist is Ownable
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L30
contract LinearInterestRate is IRateCalculator
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/LinearInterestRate.sol#L32
contract VariableInterestRate is IRateCalculator
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L33
Severity: Non-Critical
function asset() external view returns (address) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L96
Severity: Non-Critical
Use (e.g. 1e6) rather than decimal literals (e.g. 100000), for better code readability.
uint256 public DEFAULT_LIQ_FEE = 10000;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L51
Severity: Non-Critical
Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.
return maturityDate != 0 && block.timestamp > maturityDate;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L321
if (_currentRateInfo.lastTimestamp == block.timestamp) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L420
_currentRateInfo.lastTimestamp = uint64(block.timestamp);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L434
uint256 _deltaTime = block.timestamp - _currentRateInfo.lastTimestamp;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L441
if (_exchangeRateInfo.lastTimestamp == block.timestamp) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L518
_exchangeRateInfo.lastTimestamp = uint32(block.timestamp);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L544
if (block.timestamp > _deadline) revert PastDeadline(block.timestamp, _deadline);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L955
block.timestamp
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1112
Block timestamps should not be used for entropy or generating random numbersโi.e., they should not be the deciding factor (either directly or through some derivation) for winning a game or changing an important state.
Time-sensitive logic is sometimes required; e.g., for unlocking contracts (time-locking), completing an ICO after a few weeks, or enforcing expiry dates. It is sometimes recommended to use block.number and an average block time to estimate times; with a 10 second block time, 1 week equates to approximately, 60480 blocks. Thus, specifying a block number at which to change a contract state can be more secure, as miners are unable to easily manipulate the block number.
๐ Selected for report: IllIllI
Also found by: 0x1f8b, 0xA5DF, 0xDjango, 0xNazgul, 0xSmartContract, 0xackermann, 0xbepresent, 0xc0ffEE, 0xkatana, 2997ms, Amithuddar, Aymen0909, Bnke0x0, Chinmay, Chom, CodingNameKiki, Deivitto, Diraco, Dravee, ElKu, EthLedger, Fitraldys, Funen, IgnacioB, JC, Junnon, Lambda, LeoS, Metatron, MiloTruck, Noah3o6, NoamYakov, PaludoX0, Randyyy, ReyAdmirado, Rohan16, Rolezn, Ruhum, SaharAP, Sm4rty, SooYa, TomJ, Tomio, Waze, Yiko, _Adam, __141345__, a12jmx, ajtra, ak1, asutorufos, ballx, brgltd, c3phas, cRat1st0s, carlitox477, chrisdior4, d3e4, delfin454000, dharma09, djxploit, durianSausage, erictee, fatherOfBlocks, find_a_bug, flyx, francoHacker, gerdusx, gogo, gzeon, hakerbaya, ignacio, jag, kyteg, ladboy233, ltyu, m_Rassska, medikko, mics, mrpathfindr, newfork01, nxrblsrpr, oyc_109, pfapostol, rbserver, reassor, ret2basic, robee, sach1r0, saian, simon135, sryysryy, zeesaw
22.0485 USDC - $22.05
Severity: Gas Optimizations
bytes memory _rateData = abi.encode(
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L450
abi.encode(
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L213
abi.encode(CIRCUIT_BREAKER_ADDRESS, COMPTROLLER_ADDRESS, TIME_LOCK_ADDRESS, FRAXLEND_WHITELIST_ADDRESS),
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L331
abi.encode(CIRCUIT_BREAKER_ADDRESS, COMPTROLLER_ADDRESS, TIME_LOCK_ADDRESS, FRAXLEND_WHITELIST_ADDRESS),
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L374
return abi.encode(MIN_INT, MAX_INT, MAX_VERTEX_UTIL, UTIL_PREC);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/LinearInterestRate.sol#L47
return abi.encode(MIN_UTIL, MAX_UTIL, UTIL_PREC, MIN_INT, MAX_INT, INT_HALF_LIFE);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L53
Severity: Gas Optimizations
The overheads outlined below are PER LOOP, excluding the first loop
storage arrays incur a Gwarmaccess (100 gas) memory arrays use MLOAD (3 gas) calldata arrays use CALLDATALOAD (3 gas)
Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset
for (uint256 i = 0; i < _lenders.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L289
for (uint256 i = 0; i < _borrowers.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L308
for (uint256 i = 0; i < _approvedBorrowers.length; ++i) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L265
for (uint256 i = 0; i < _approvedLenders.length; ++i) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L270
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L51
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L66
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L81
Severity: Gas Optimizations
When a function with a memory array is called externally, the abi.decode() step has to use a for-loop to copy each index of the calldata to the memory index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * <mem_array>.length). Using calldata directly, obliviates the need for such a loop in the contract code and runtime execution. Structs have the same overhead as an array of length one
address[] memory _path
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1067
function getAllPairAddresses() external view returns (address[] memory) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L122
returns (PairCustomStatus[] memory _pairCustomStatuses)
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L147
address[] memory _approvedBorrowers, address[] memory _approvedLenders
address[] memory _approvedBorrowers, address[] memory _approvedLenders
function globalPause(address[] memory _addresses) external returns (address[] memory _updatedAddresses) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L398
Severity: Gas Optimizations
The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the contract is meant to be extended, the contract should be abstract and the function signatures be added without any default implementation. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if(x){}else if(y){...}else{...} => if(!x){if(y){...}else{...}})
} catch {}
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L406
function requireValidInitData(bytes calldata _initData) external pure {}
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L57
Severity: Gas Optimizations
Saves 6 gas per loop
for (uint256 i = 0; i < _lenders.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L289
for (uint256 i = 0; i < _borrowers.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L308
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L51
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L66
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L81
For example, use ++i instead of i++
Severity: Gas Optimizations
for (uint256 i = 0; i < _lenders.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L289
for (uint256 i = 0; i < _borrowers.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L308
for (uint256 i = 0; i < _approvedBorrowers.length; ++i) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L265
for (uint256 i = 0; i < _lengthOfArray; ) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L402
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L51
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L66
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L81
Severity: Gas Optimizations
Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.
mapping(address => bool) public swappers; mapping(address => bool) public approvedLenders;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L78
mapping(address => bool) public oracleContractWhitelist; mapping(address => bool) public rateContractWhitelist; mapping(address => bool) public fraxlendDeployerWhitelist;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L32
Severity: Gas Optimizations
_totalAsset.amount -= uint128(_amountToTransfer);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L252
_totalAsset.shares -= _shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L253
_totalBorrow.amount += uint128(_interestEarned);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L475
_totalAsset.amount += uint128(_interestEarned);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L476
_totalAsset.shares += uint128(_feesShare);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L484
_totalAsset.amount += _amount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L566
_totalAsset.shares += _shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L567
_totalAsset.amount -= _amountToReturn;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L643
_totalAsset.shares -= _shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L644
_totalBorrow.amount += _borrowAmount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L718
_totalBorrow.shares += uint128(_sharesAdded);
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L719
userBorrowShares[msg.sender] += _sharesAdded;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L724
userCollateralBalance[_borrower] += _collateralAmount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L772
totalCollateral += _collateralAmount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L773
userCollateralBalance[_borrower] -= _collateralAmount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L813
totalCollateral -= _collateralAmount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L815
_totalBorrow.amount -= _amountToRepay;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L863
_totalBorrow.shares -= _shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L864
userBorrowShares[_borrower] -= _shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L867
totalAsset.amount -= _amountToAdjust;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1008
_totalBorrow.amount -= _amountToAdjust;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1011
_totalBorrow.shares -= _sharesToAdjust;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1012
Severity: Gas Optimizations
The following functions could be set external to save gas and improve code quality. External call cost is less expensive than of public functions.
function name() public view override(ERC20, IERC20Metadata) returns (string memory) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L74
function symbol() public view override(ERC20, IERC20Metadata) returns (string memory) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L78
function decimals() public pure override(ERC20, IERC20Metadata) returns (uint8) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L84
function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L89
function totalAssets() public view virtual returns (uint256) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L100
function requireValidInitData(bytes calldata _initData) public pure {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/LinearInterestRate.sol#L52
Severity: Gas Optimizations
require(deployedPairsBySalt[salt] == address(0), "FraxlendPairDeployer: Pair already deployed");
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L205
require(_pairAddress != address(0), "FraxlendPairDeployer: create2 failed");
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L228
require(deployedPairsByName[_name] == address(0), "FraxlendPairDeployer: Pair name must be unique");
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L253
require(_maxLTV <= GLOBAL_MAX_LTV, "FraxlendPairDeployer: _maxLTV is too large");
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L365
Severity: Gas Optimizations
Lower than uint256 size storage variables are less gas efficient. Using uint64 does not give any efficiency, actually, it is the opposite as EVM operates on default of 256-bit values so uint64 is more expensive in this case as it needs a conversion. It only gives improvements in cases where you can pack variables together, e.g. structs.
uint64 internal constant DEFAULT_INT = 158247046;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairConstants.sol#L41
uint16 internal constant DEFAULT_PROTOCOL_FEE = 0;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairConstants.sol#L47
uint64 lastBlock;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L106
uint64 feeToProtocolRate;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L107
uint64 lastTimestamp;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L108
uint64 ratePerSec;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L109
uint32 lastTimestamp;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L116
uint224 exchangeRate;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L117
uint128 _borrowerShares = userBorrowShares[_borrower].toUint128();
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L967
uint128 _amountLiquidatorToRepay = (_totalBorrow.toAmount(_sharesToLiquidate, true)).toUint128();
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L993
uint128 _sharesToAdjust;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L997
uint128 _amountToAdjust;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L998
uint128 _leftoverBorrowShares = _borrowerShares - _sharesToLiquidate;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L1001
uint32 private constant MIN_UTIL = 75000;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L35
uint32 private constant MAX_UTIL = 85000;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L36
uint32 private constant UTIL_PREC = 1e5;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L37
uint64 private constant MIN_INT = 79123523;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L40
uint64 private constant MAX_INT = 146248508681;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/VariableInterestRate.sol#L41
uint8 i = 0;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/SafeERC20.sol#L22
uint128 amount;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/VaultAccount.sol#L5
uint128 shares;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/VaultAccount.sol#L6
Severity: Gas Optimizations
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP
for (uint256 i = 0; i < _lenders.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L289
for (uint256 i = 0; i < _borrowers.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L308
for (uint256 i = 0; i < _approvedBorrowers.length; ++i) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L265
for (uint256 i = 0; i < _approvedLenders.length; ++i) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L270
for (i = 0; i < _lengthOfArray; ) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L127
for (i = 0; i < _lengthOfArray; ) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L152
for (uint256 i = 0; i < _lengthOfArray; ) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L402
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L51
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L66
for (uint256 i = 0; i < _addresses.length; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L81
for (i = 0; i < 32 && data[i] != 0; i++) {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/libraries/SafeERC20.sol#L27
Severity: Gas Optimizations
Save 6 gas per instance if using assembly to check for address(0)
e.g. assembly { if iszero(_addr) { mstore(0x00, "AddressZero") revert(0x00, 0x20) } }
function setTimeLock(address _newAddress) external onlyOwner {
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPair.sol#L204
Severity: Gas Optimizations
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.
mapping(address => bool) public swappers;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L78
bool public immutable borrowerWhitelistActive; https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L133
mapping(address => bool) public approvedBorrowers;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L134
bool public immutable lenderWhitelistActive; https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L136
mapping(address => bool) public approvedLenders;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairCore.sol#L137
mapping(address => bool) public deployedPairCustomStatusByAddress;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendPairDeployer.sol#L94
mapping(address => bool) public oracleContractWhitelist;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L32
mapping(address => bool) public rateContractWhitelist;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L35
mapping(address => bool) public fraxlendDeployerWhitelist;
https://github.com/code-423n4/2022-08-frax/tree/main/src/contracts/FraxlendWhitelist.sol#L38