Platform: Code4rena
Start Date: 26/01/2023
Pot Size: $60,500 USDC
Total HM: 7
Participants: 31
Period: 6 days
Judge: berndartmueller
Total Solo HM: 3
Id: 207
League: ETH
Rank: 20/31
Findings: 1
Award: $142.48
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: CodingNameKiki
Also found by: 0xAgro, 0xSmartContract, IllIllI, Rolezn, SleepingBugs, btk, chrisdior4, matrix_0wl
142.4841 USDC - $142.48
L-N | Issue |
---|---|
[L‑01] | Missing non-zero address checks in constructor in LiquidityManager and LendgineRouter |
Total: 1 issue
N-C | Issue |
---|---|
[NC‑01] | Constants should be capitalized |
[NC‑02] | Use x != 0 to get positive-only uint values |
[NC‑03] | Use latest Solidity version with a stable pragma statement |
[NC‑04] | Events, structs and custom errors declaration |
[NC‑05] | Constants should be defined rather than using magic numbers |
[NC‑06] | Typos in comments |
[NC‑07] | Incomplete NatSpec |
Total: 6 issues
LiquidityManager
and LendgineRouter
In LiquidityManager
the address variable factory
is immutable and set in the constructor which is only callable once. If any errors are made when passing the argument for factory
in the constructors, they will be irreversable.
constructor(address _factory, address _weth) Payment(_weth) { factory = _factory; }
constructor( address _factory, address _uniswapV2Factory, address _uniswapV3Factory, address _weth ) SwapHelper(_uniswapV2Factory, _uniswapV3Factory) Payment(_weth) { factory = _factory; }
Consider adding such checks for both contracts.
File: JumpRate.sol
uint256 public constant override kink = 0.8 ether; uint256 public constant override multiplier = 1.375 ether; uint256 public constant override jumpMultiplier = 44.5 ether;
The "positive uint" checks in the code are not done in the best possible way, one example is (decoded.amount0 > 0)
- if a number is expected to be of a uint type, then you can check that it is positive by doing x != 0 since uint can never be a negative number. Replace all x > 0 occurrences with x != 0 when x is a uint.
Example in LiquidityManager
:
if (decoded.amount0 > 0) pay(decoded.token0, decoded.payer, msg.sender, decoded.amount0);
Using a floating pragma ^0.8.4 statement is discouraged as code can compile to different bytecodes with different compiler versions. Use a stable pragma statement to get a deterministic bytecode. Also use latest Solidity version to get all compiler features, bugfixes and optimizations
It is a best practice to be declared in the interface not in the implementation contract.
Files: Lendgine
and Factory
File: Factory.sol
if (token0Exp > 18 || token0Exp < 6 || token1Exp > 18 || token1Exp < 6) revert ScaleError();
File: Lendgine.sol
return FullMath.mulDiv(liquidity, 2 * upperBound, 1e18) / token1Scale;
File: LiquidityManager.sol
Change liqudity
=> liquidity
File: ILendgine.sol
Change recieves
=> receives
IJumpRate.sol
is missing natspec documenation, and some other contracts are missing @param comments. NatSpec documentation to all public methods and variables is essential for better understanding of the code by developers and auditors and is strongly recommended. Consider adding a full NatSpec documentation.
#0 - c4-judge
2023-02-16T11:44:51Z
berndartmueller marked the issue as grade-b