Platform: Code4rena
Start Date: 03/11/2022
Pot Size: $115,500 USDC
Total HM: 17
Participants: 120
Period: 7 days
Judge: LSDan
Total Solo HM: 1
Id: 174
League: ETH
Rank: 62/120
Findings: 2
Award: $110.58
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xNazgul, 0xRoxas, 0xSmartContract, Awesome, Aymen0909, B2, BClabs, Bnke0x0, Deekshith99, Deivitto, Diana, Dinesh11G, Funen, HE1M, HardlyCodeMan, Josiah, Nyx, Rahoz, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Saintcode_, TomJ, Trust, __141345__, a12jmx, adriro, ajtra, aphak5010, apostle0x01, brgltd, btk, bulej93, c3phas, carlitox477, catwhiskeys, ch0bu, chaduke, chrisdior4, cryptonue, cryptostellar5, csanuragjain, ctf_sec, delfin454000, djxploit, durianSausage, erictee, fatherOfBlocks, gogo, i_got_hacked, immeas, joestakey, jumpdest7d, lukris02, martin, mcwildy, merlin, minhquanym, oyc_109, pashov, peanuts, pedr02b2, rbserver, rotcivegaf, rvierdiiev, sakman, saneryee, seyni, shark, slowmoses, tnevler, trustindistrust, w0Lfrum, yurahod, zaskoh
61.3462 USDC - $61.35
In the contracts, floating pragmas should not be used. Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
There are multiple instances of this issue
Some instances include:
File: contracts/modules/credit/LineOfCredit.sol 1: pragma solidity ^0.8.9;
File: contracts/modules/credit/SecuredLine.sol 1: pragma solidity ^0.8.9;
Lock the pragma version
There is 1 instance of this issue
File: contracts/utils/SpigotedLineLib.sol 134: IERC20(sellToken).approve(swapTarget, amount);
Add safeincreaseAllowance and safedecreaseAllowance methods in ERC20 contract
Each event
should use three indexed
fields if there are three or more fields
There are 3 instances of this issue
File: contracts/utils/SpigotLib.sol 241-244: event AddSpigot( address indexed revenueContract, uint256 ownerSplit ); 255-260: event ClaimRevenue( address indexed token, uint256 indexed amount, uint256 escrowed, address revenueContract ); 262-266: event ClaimEscrow( address indexed token, uint256 indexed amount, address owner );
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.
There are 5 instances of this issue
File: contracts/modules/credit/LineOfCredit.sol 58: deadline = block.timestamp + ttl_; 132: if (block.timestamp >= deadline && count > 0) {
File: contracts/modules/interest-rate/InterestRateCredit.sol 48: uint256 timespan = block.timestamp - rate.lastAccrued; 50: rates[id].lastAccrued = block.timestamp; 82: lastAccrued: block.timestamp
It's a best practice to use the latest compiler version.
The specified minimum compiler version is quite old. Older compilers might be susceptible to some bugs. We recommend changing the solidity version pragma to the latest version to enforce the use of an up to date compiler.
List of known compiler bugs and their severity can be found here: https://etherscan.io/solcbuginfo
There are multiple instances of this issue
Some instances include:
File: contracts/modules/credit/EscrowedLine.sol 1: pragma solidity 0.8.9;
File: contracts/utils/Spigot.sol 1: pragma solidity 0.8.9;
#0 - c4-judge
2022-12-06T23:00:19Z
dmvt marked the issue as grade-b
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xRajkumar, Awesome, Aymen0909, B2, Bnke0x0, Deivitto, Diana, JC, Metatron, Rahoz, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Saintcode_, TomJ, __141345__, ajtra, aphak5010, brgltd, c3phas, ch0bu, chrisdior4, cryptonue, durianSausage, emrekocak, erictee, exolorkistis, gogo, karanctf, lukris02, martin, me_na0mi, oyc_109, peanuts, rotcivegaf, saneryee, seyni, tnevler, zaskoh
49.2315 USDC - $49.23
There are 20 instances of this issue
File: contracts/modules/credit/LineOfCredit.sol 192: principal += _p; 193: interest += _i; 276: credit.deposit += amount; 351: credit.principal += amount;
File: contracts/modules/credit/SpigotedLine.sol 122: unusedTokens[credit.token] -= repaid - newTokens; 125: unusedTokens[credit.token] += newTokens - repaid; 144: unusedTokens[credit.token] -= amount; 172: unusedTokens[targetToken] += newTokens;
File: contracts/utils/CreditLib.sol 177: credit.interestAccrued -= amount; 178: credit.interestRepaid += amount; 186: credit.principal -= principalPayment; 187: credit.interestRepaid += interest; 216: amount -= interest; 218: credit.deposit -= amount; 227: credit.interestRepaid -= amount; 258: credit.interestAccrued += accruedToken;
File: contracts/utils/EscrowLib.sol 75: collateralValue += CreditLib.calculateValue( 96: self.deposited[token].amount += amount; 164: self.deposited[token].amount -= amount; 202: self.deposited[token].amount -= amount;
In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline
Prior to Solidity 0.8.0, arithmetic operations would always wrap in case of under- or overflow leading to widespread use of libraries that introduce additional checks.
Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default, thus making the use of these libraries unnecessary.
To obtain the previous behaviour, an unchecked block can be used
There are 6 instances of this issue
File: contracts/modules/credit/LineOfCredit.sol 179: for (uint256 i; i < len; ++i) { 203: for (uint256 i; i < len; ++i) { 520: for (uint256 i; i <= lastSpot; ++i) {
File: contracts/utils/CreditListLib.sol 23: for(uint256 i; i < len; ++i) { 51: for(uint i = 1; i < len; ++i) {
File: contracts/utils/EscrowLib.sol 57: for (uint256 i; i < length; ++i) {
Not inlining costs 20 to 40 gas because of two extra JUMP
instructions and additional stack operations needed for function calls.
There are 4 instances of this issue
File: contracts/modules/credit/EscrowedLine.sol 89: function _rollover(address newLine) internal virtual returns(bool) {
File: contracts/modules/credit/LineOfCredit.sol 435: function _createCredit( 516: function _sortIntoQ(bytes32 p) internal returns (bool) {
File: contracts/utils/MutualConsent.sol 65: function _getNonCaller(address _signerOne, address _signerTwo) internal view returns(address) {
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed
There are 15 instances of this issue
File: contracts/modules/credit/SecuredLine.sol 21: uint8 defaultSplit_
File: contracts/modules/credit/SpigotedLine.sol 60: uint8 defaultRevenueSplit_
File: contracts/modules/escrow/Escrow.sol 43: uint32 _minimumCollateralRatio,
File: contracts/modules/factories/LineFactory.sol 43: uint32 minCRatio, 71: uint8 split = defaultRevenueSplit;
File: contracts/utils/CreditLib.sol 112: uint8 decimals 138: uint8 decimals;
File: contracts/utils/LineFactoryLib.sol 13: uint8 revenueSplit 25: uint32 indexed minCRatio, 51: uint8 split = SecuredLine(oldLine).defaultRevenueSplit(); 85: uint8 revenueSplit
File: contracts/utils/SpigotedLineLib.sol 169-170: function updateSplit(address spigot, address revenueContract, LineLib.STATUS status, uint8 defaultSplit) external returns (bool) { (uint8 split,, bytes4 transferFunc) = ISpigot(spigot).getSetting(revenueContract);
File: contracts/utils/SpigotLib.sol 164: unction updateOwnerSplit(SpigotState storage self, address revenueContract, uint8 ownerSplit) 252: uint8 indexed split
_There are 5 instances of this issue
File: contracts/modules/credit/LineOfCredit.sol 241: require(interestRate.setRate(id, drate, frate)); 259: require(interestRate.setRate(id, drate, frate));
File: contracts/utils/EscrowLib.sol 91: require(amount > 0); 161: require(amount > 0); 198: require(amount > 0);
Removing unused named returns variables can reduce gas usage (MSTOREs/MLOADs) and improve code clarity. To save gas and improve code quality: consider using only one of those.
_There are 7 instances of this issue
File: contracts/utils/Spigot.sol 70-72: function claimRevenue(address revenueContract, address token, bytes calldata data) external nonReentrant returns (uint256 claimed) 85-88: function claimEscrow(address token) external nonReentrant returns (uint256 claimed)
File: contracts/utils/CreditLib.sol 73-80: function getOutstandingDebt( ILineOfCredit.Credit memory credit, bytes32 id, address oracle, address interestRate ) external returns (ILineOfCredit.Credit memory c, uint256 principal, uint256 interest) 125-133: function create( bytes32 id, uint256 amount, address lender, address token, address oracle ) external returns(ILineOfCredit.Credit memory credit)
File: contracts/utils/SpigotLib.sol 29-31: function _claimRevenue(SpigotState storage self, address revenueContract, address token, bytes calldata data) public returns (uint256 claimed) 83-85: function claimRevenue(SpigotState storage self, address revenueContract, address token, bytes calldata data) external returns (uint256 claimed) 105-107: function claimEscrow(SpigotState storage self, address token) external returns (uint256 claimed)
#0 - c4-judge
2022-11-17T23:02:40Z
dmvt marked the issue as grade-b