Platform: Code4rena
Start Date: 29/03/2022
Pot Size: $30,000 USDC
Total HM: 6
Participants: 24
Period: 3 days
Judge: HardlyDifficult
Total Solo HM: 4
Id: 101
League: ETH
Rank: 20/24
Findings: 1
Award: $59.96
🌟 Selected for report: 0
🚀 Solo Findings: 0
59.9633 USDC - $59.96
gas
#1 Gas improvement on calling SafeERC20.function
By removing L26 and calling SafeERC20.function
directly at line which calling the function can save gas per call
For instance: L754
SafeERC20.safeTransferFrom(_collateralAsset, msg.sender, address(this), _amount);
Can also implemented on SafeMath but not recommended because of readibilty
#2 Using multiple require()
instead of &&
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L406
By using multiple require()
than && can save execution gas cost.
#3 Gas improvement when validating with isWithinLimits
function
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L368-L386
By removing the isWithinLimits
returns and validate directly in it instead of checking the isWithinLimits
value == true can save both deployment and execution gas:
function isWithinLimits( uint256 _value, uint256 _min, uint256 _max ) internal pure{ if (_min != 0 && _max != 0) { // If both min and max limits exist require(_value >= _min && _value <= _max,'ILB1'); //@audit-info validate here } else if (_min != 0) { // if only min limit exists require(_value >= _min); } else if (_max != 0) { // if only max limit exists require(_value <= _max); }//@audit-info remove else because no need to validate if both _min && _max == 0 } function foo()external pure{ isWithinLimits(0,0,0); //@audit-info call it without require() }
Currently there are a lot isWithinLimits
call in the contract included with require()
so it can also save deployment gas by calling the function without require()
#4 Placement of require statement in _limitBorrowedInUSD
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L394
The require()
statement can be place earlier to prevent execution of code above it in case the value of it == false to save gas
#5 Unnecessary withdrawableCollateral
MSTORE
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L777
By calling withdrawableCollateral(_id)
directly to L778 without caching it can save gas. The withdrawableCollateral
var was just called once in the function:
//@audit-info remove L777 require(_amount <= _withdrawableCollateral(_id), 'WC1');
#6 Relocation of if() condition check
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L950
Its imposible _max <= _currentDebt == true if _maxPossible == type(uint).max. This condition will only occur inside if(collateralRatio != 0)
, therefore put it inside the if condition (L944) will prevent if (_maxPossible <= _currentDebt)
code read:
if (_collateralRatio != 0) { _maxPossible = _totalCollateralToken.mul(_ratioOfPrices).div(_collateralRatio).mul(SCALING_FACTOR).div(10**_decimals); if (_maxPossible <= _currentDebt) return 0; }
#7 Using > is cheaper than >=
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/LenderPool.sol#L315
1 second difference can be ignored to validate _startTime
using > can save gas
#8 Avoiding SLOAD to emit event
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/Verification/twitterVerifier.sol#L209
Use _signerAddress
to emit SignerUpdated
event
#9 Using at least pragma solidity 0.8.4
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/PooledCreditLine.sol#L2
Some contract are using SafeMath
lib to do math operation. By using pragma 0.8.4, the gas cost can be reduced due to SafeMath by default
#10 caching var.length for loop https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/LenderPool.sol#L670 By caching ids.length to newVar, can save gas:
Uint newVar = ids.lenght for (uint256 i; i < newVar; ++i)
#11 Store array parameters in calldata
https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/LenderPool.sol#L665-L666
using calldata to store ids
and amounts
can save gas
#12 using -= for gas saving https://github.com/sublime-finance/sublime-v1/blob/46536a6d25df4264c1b217bd3232af30355dcb95/contracts/PooledCreditLine/LenderPool.sol#L681
totalSupply[id] -= amount
#0 - ritik99
2022-04-12T19:15:16Z
All except suggestion no. 9 are valid since we cannot upgrade to v0.8 because of a dependency (see #67 )