Platform: Code4rena
Start Date: 08/09/2023
Pot Size: $70,000 USDC
Total HM: 8
Participants: 84
Period: 6 days
Judge: gzeon
Total Solo HM: 2
Id: 285
League: ETH
Rank: 68/84
Findings: 1
Award: $12.79
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: castle_chain
Also found by: 0xAadi, 0xHelium, 0xLook, 0xblackskull, 0xfuje, 0xmystery, 0xnev, 0xpiken, 7ashraf, BARW, Bauchibred, Bughunter101, Ch_301, JP_Courses, Kaysoft, Krace, MohammedRizwan, SanketKogekar, Sathish9098, alexzoid, ast3ros, btk, catellatech, degensec, fatherOfBlocks, grearlake, imtybik, jkoppel, jolah1, klau5, lsaudit, m_Rassska, merlin, mrudenko, nobody2018, rokinot, rvierdiiev, sandy
12.7917 USDC - $12.79
commented codes sometimes may indicate unfinished work.
function mint(uint256 shares, address receiver) public returns (uint256 assets) { // require(receiver == msg.sender, "LiquidityPool/not-authorized-to-mint");//@audit-info commented code. assets = investmentManager.processMint(receiver, shares); emit Deposit(address(this), receiver, assets, shares); }
Consider removing commented codes.
ApproveLike
interface in the Escrow.sol
file is unused.Consider removing unused interface.
liquidityPool
in the InvestmentManager.sol#_toPriceDecimals() function is unused.
File: https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/InvestmentManager.sol#L676_price
local variable in the Gateway.sol#handle() function is unused.File: https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/gateway/Gateway.sol#L302 Consider removing unused variables.
Consider adding comments for each struct field to improve readability of the codebase.
Pool
struct are not commented.struct Pool {//@audit-info uncommented fields of a struct uint64 poolId; uint256 createdAt; mapping(bytes16 => Tranche) tranches; mapping(address => bool) allowedCurrencies; }
File: https://github.com/code-423n4/2023-09-centrifuge/blob/main/src/PoolManager.sol#L53-L58
struct Tranche { address token;//@audit-info comment struct. uint64 poolId; bytes16 trancheId; // important: the decimals of the leading pool currency. Liquidity Pool shares have to be denomatimated with the same precision. uint8 decimals; uint256 createdAt; string tokenName; string tokenSymbol; /// @dev Each tranche can have multiple liquidity pools deployed, /// each linked to a unique investment currency (asset) mapping(address => address) liquidityPools; // currency -> liquidity pool address }
File: https://github.com/code-423n4/2023-09-centrifuge/blob/main/src/PoolManager.sol#L61-L73
Pause()
and Unpause()
events.The Pause()
and Unpause()
events does not include information of the person who paused the system. Consider adding the address of the pause to the Pause()
and Unpause()
events.
File: https://github.com/code-423n4/2023-09-centrifuge/blob/main/src/Root.sol#L27-L28
event Pause();//@audit add address of pauser. event Unpause();
The PausableAdmin contract title has "Delayed Admin" on it. The title should be "Pausable Admin".
/// @title Delayed Admin @audit-info this should be Pause Admin. /// @dev Any ward can manage accounts who can pause. /// Any pauser can instantaneously pause the Root. contract PauseAdmin is Auth { Root public immutable root; ...
ERC20.sol has all the state, events and functions in the Auth.sol contract. Consider making ERC20.sol inherit from Auth.sol to reduce code duplications.
Files:
wards
parameter of the newLiquidityPool()
function shadows Auth.sol.wards state variable.wards
parameter of the newLiquidityPool()
function shadows Auth.sol.wards state variable. Consider renaming the parameter to avoid variable shadowing.
contract LiquidityPoolFactory is Auth { address immutable root; constructor(address _root) { root = _root; wards[msg.sender] = 1; emit Rely(msg.sender); } function newLiquidityPool( uint64 poolId, bytes16 trancheId, address currency, address trancheToken, address investmentManager, address[] calldata wards ) public auth returns (address) { LiquidityPool liquidityPool = new LiquidityPool(poolId, trancheId, currency, trancheToken, investmentManager); liquidityPool.rely(root); for (uint256 i = 0; i < wards.length; i++) {//@audit variable shadowing wards. liquidityPool.rely(wards[i]); } ...
#0 - c4-pre-sort
2023-09-17T01:41:34Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-09-26T17:38:28Z
gzeon-c4 marked the issue as grade-b