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: 60/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
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth))
). Having no access control on the function means that someone may send Ether to the contract, and have no way to get anything back out, which is a loss of funds
272 receive() external payable {}
Constructors should check the address written in an immutable address variable is not the zero address.
56 arbiter = arbiter_; 57 borrower = borrower_;
66 swapTarget = swapTarget_;
49 oracle = _oracle; 50 borrower = _borrower;
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.
https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/LineOfCredit.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/SpigotedLine.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/SecuredLine.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/oracle/Oracle.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/interest-rate/InterestRateCredit.sol
string.concat()
instead of abi.encodePacked(<str>,<str>)
using for
with a list of free functionsAll contracts use Solidity 0.8.9 version
https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/LineOfCredit.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/SpigotedLine.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/SecuredLine.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/credit/EscrowedLine.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/spigot/Spigot.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/escrow/Escrow.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/interest-rate/InterestRateCredit.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/modules/factories/LineFactory.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/CreditLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/CreditListLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/EscrowLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/SpigotLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/SpigotedLineLib.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/MutualConsent.sol https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineFactoryLib.sol
Scientific notation should be used for better code readability
42 uint256 _numerator = collateralValue * 10**5; // scale to 4 decimals
nonReentrant modifier
should occur before all other modifiersThis is a best-practice to protect against reentrancy in other modifiers
93 function claimAndRepay(address claimToken, bytes calldata zeroExTradeData) 94 external 95 whileBorrowing 96 nonReentrant 97 returns (uint256) 98 {
Check here for NatSpec rules: https://docs.soliditylang.org/en/develop/natspec-format.html
Most of the contracts are missing @title and @author tags A lot of functions are missing @param and @return tags that explain input/output variables
indexed
fieldsIndex event fields make the field more quickly accessible to off-chain tools that parse events. Each event
should use three indexed
fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.
241 event AddSpigot( 242 address indexed revenueContract, 243 uint256 ownerSplit ... 255 event ClaimRevenue( 256 address indexed token, 257 uint256 indexed amount, 258 uint256 escrowed, 259 address revenueContract ... 262 event ClaimEscrow( 263 address indexed token, 264 uint256 indexed amount, 265 address owner
#0 - c4-judge
2022-12-06T17:36:33Z
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
All contracts use Solidity version 0.8.9
uint/int
smaller than 32 bytes (256 bits) incurs overheadWhen 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 Each operation involving a uint8
costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8
) as compared to ones involving uint256
, due to the compiler having to clear the higher bits of the memory word before operating on the uint8
, as well as the associated stack operations of doing so. Use a larger size then downcast where needed.
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{...}}
). Empty receive()
/fallback()
payable functions that are not used, can be removed to save deployment gas.
272 receive() external payable {}
Constructor parameters are expensive. The contract deployment will be cheaper in gas if they are hard coded instead of using constructor parameters.
55 oracle = IOracle(oracle_); 56 arbiter = arbiter_; 57 borrower = borrower_;
64 spigot = ISpigot(spigot_); 65 defaultRevenueSplit = defaultRevenueSplit_; 66 swapTarget = swapTarget_;
48 minimumCollateralRatio = _minimumCollateralRatio; 49 oracle = _oracle; 50 borrower = _borrower; 51 state.line = _line;
36 arbiter = arbiter_; 37 oracle = oracle_; 38 swapTarget = swapTarget_;
#0 - c4-judge
2022-11-17T22:53:09Z
dmvt marked the issue as grade-b