Platform: Code4rena
Start Date: 13/02/2024
Pot Size: $24,500 USDC
Total HM: 5
Participants: 84
Period: 6 days
Judge: 0xA5DF
Id: 331
League: ETH
Rank: 27/84
Findings: 4
Award: $121.23
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: BowTiedOriole
Also found by: 0x0bserver, 0xAadi, 0xJoyBoy03, 0xlamide, 0xlemon, 0xpiken, Babylen, Breeje, Brenzee, CodeWasp, DanielArmstrong, DarkTower, Fassi_Security, Fitro, Honour, JohnSmith, Krace, MrPotatoMagic, Myrault, ReadyPlayer2, SovaSlava, SpicyMeatball, TheSavageTeddy, Tigerfrake, atoko, cryptphi, csanuragjain, d3e4, gesha17, kinda_very_good, krikolkk, matejdb, max10afternoon, miaowu, n0kto, nuthan2x, parlayan_yildizlar_takimi, peanuts, petro_1912, pontifex, psb01, pynschon, rouhsamad, shaflow2, slippopz, spark, turvy_fuzz, web3pwn, zhaojohnson
3.5914 USDC - $3.59
Judge has assessed an item in Issue #308 as 3 risk. The relevant finding follows:
function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { require(!LockedForDistribution, "distribution in progress"); if (!(to == address(0))) { require( isApprovedHolder(to), "receiver not approved to hold the token" ); } if (from == address(0) || to == address(0)) { _beforeMintOrBurn(); } bool exists = (this.balanceOf(to) != 0); if (!exists) { holders.push(to); } }
#0 - c4-judge
2024-03-08T14:06:34Z
0xA5DF marked the issue as duplicate of #77
#1 - c4-judge
2024-03-08T14:06:38Z
0xA5DF marked the issue as satisfactory
#2 - c4-judge
2024-03-08T14:06:42Z
0xA5DF marked the issue as partial-50
🌟 Selected for report: 0xloscar01
Also found by: 0xAadi, 0xpiken, BowTiedOriole, Breeje, Fassi_Security, JohnSmith, Limbooo, SpicyMeatball, Tendency, Topmark, ZanyBonzy, aslanbek, atoko, jesjupyter, matejdb, max10afternoon, n0kto, peanuts, pkqs90, rouhsamad, thank_you, zhaojohnson
80.5583 USDC - $80.56
https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/bd6ee47162368e1999a0a5b8b17b701347cf9a7d/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L116-L119 https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/bd6ee47162368e1999a0a5b8b17b701347cf9a7d/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L214-L231
revenue tokens cannot be distributed completely because of disapproved holders
In current implementation, disapproved holders cannot receive any more underlying ERC20 tokens. And they may hold some LiquidInfrastructureERC20 tokens, which may influence erc20EntitlementPerUnit calculation.
For example:
uint256 supply = this.totalSupply(); for (uint i = 0; i < distributableERC20s.length; i++) { uint256 balance = IERC20(distributableERC20s[i]).balanceOf( address(this) ); uint256 entitlement = balance / supply; erc20EntitlementPerUnit.push(entitlement); }
Manual
We need to add one state to monitor activeSupply for all approved holders.
Math
#0 - c4-pre-sort
2024-02-21T02:38:05Z
0xRobocop marked the issue as duplicate of #703
#1 - c4-judge
2024-03-04T14:37:53Z
0xA5DF marked the issue as satisfactory
#2 - c4-judge
2024-03-08T15:15:56Z
0xA5DF changed the severity to 2 (Med Risk)
🌟 Selected for report: nuthan2x
Also found by: 0x0bserver, AM, CaeraDenoir, DanielArmstrong, JrNet, Kirkeelee, KmanOfficial, Krace, Limbooo, Meera, SovaSlava, SpicyMeatball, TheSavageTeddy, agadzhalov, aslanbek, atoko, csanuragjain, d3e4, imare, jesjupyter, juancito, kartik_giri_47538, kutugu, max10afternoon, offside0011, pkqs90, turvy_fuzz, xchen1130, zhaojohnson, ziyou-
25.7286 USDC - $25.73
https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/bd6ee47162368e1999a0a5b8b17b701347cf9a7d/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L441-L445 https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/bd6ee47162368e1999a0a5b8b17b701347cf9a7d/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L257-L281 https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/bd6ee47162368e1999a0a5b8b17b701347cf9a7d/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L214-L231
owner can call setDistributableERC20s in the distribution, which may cause dos
In the start of distribution, system will calculate erc20EntitlementPerUnit based on current distributableERC20s. If owner changes distributableERC20s in the process of distribution, token distribution may be wrong.
For example,
for (uint j = 0; j < distributableERC20s.length; j++) { IERC20 toDistribute = IERC20(distributableERC20s[j]); uint256 entitlement = erc20EntitlementPerUnit[j] * this.balanceOf(recipient); if (toDistribute.transfer(recipient, entitlement)) { receipts[j] = entitlement; } }
Manual
Disable setDistributableERC20s() in the process of distribute
DoS
#0 - c4-pre-sort
2024-02-21T02:40:46Z
0xRobocop marked the issue as duplicate of #260
#1 - c4-judge
2024-03-04T15:30:50Z
0xA5DF marked the issue as satisfactory
#2 - c4-judge
2024-03-08T15:26:19Z
0xA5DF changed the severity to 2 (Med Risk)
🌟 Selected for report: ZanyBonzy
Also found by: 0xSmartContractSamurai, DarkTower, MrPotatoMagic, SpicyMeatball, TheSavageTeddy, jesjupyter, lsaudit, peanuts, zhaojohnson
11.348 USDC - $11.35
[L01] invalid require() in function releaseManagedNFT()
function releaseManagedNFT( address nftContract, address to ) public onlyOwner nonReentrant { LiquidInfrastructureNFT nft = LiquidInfrastructureNFT(nftContract); nft.transferFrom(address(this), to, nft.AccountId()); // Remove the released NFT from the collection for (uint i = 0; i < ManagedNFTs.length; i++) { address managed = ManagedNFTs[i]; if (managed == nftContract) { // Delete by copying in the last element and then pop the end ManagedNFTs[i] = ManagedNFTs[ManagedNFTs.length - 1]; ManagedNFTs.pop(); break; } } // By this point the NFT should have been found and removed from ManagedNFTs require(true, "unable to find released NFT in ManagedNFTs"); emit ReleaseManagedNFT(nftContract, to); }
[L02] Add some check in constructor about _managedNFTs. In Function addManagedNFT(), if we want to add one managedNFT, we have one check to make sure the ownership of NFT. In order to the consistency, we'd better to add similar check in constructor()
constructor( string memory _name, string memory _symbol, address[] memory _managedNFTs, address[] memory _approvedHolders, uint256 _minDistributionPeriod, address[] memory _distributableErc20s ) ERC20(_name, _symbol) Ownable() { //@johnson,[L] in addManagedNFT, when add one NFT, we need to check ownership, suggest do the same check here ManagedNFTs = _managedNFTs;
function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { require(!LockedForDistribution, "distribution in progress"); if (!(to == address(0))) { require( isApprovedHolder(to), "receiver not approved to hold the token" ); } if (from == address(0) || to == address(0)) { _beforeMintOrBurn(); } bool exists = (this.balanceOf(to) != 0); if (!exists) { holders.push(to); } }
#0 - c4-pre-sort
2024-02-22T16:57:24Z
0xRobocop marked the issue as high quality report
#1 - ChristianBorst
2024-03-02T02:29:10Z
Acknowledged: This line was left in by mistake.
Confirmed. I believe this is also a duplicate in another QA.
Confirmed. I believe this is also a duplicate somewhere else.
#2 - c4-sponsor
2024-03-02T02:29:16Z
ChristianBorst (sponsor) acknowledged
#3 - 0xA5DF
2024-03-08T11:16:22Z
+L from #90 +L from #288
#4 - 0xA5DF
2024-03-08T14:06:51Z
4L +L from #286 =5L
#5 - c4-judge
2024-03-08T14:27:30Z
0xA5DF marked the issue as grade-c
#6 - c4-judge
2024-03-09T08:04:58Z
0xA5DF marked the issue as grade-b
#7 - c4-judge
2024-03-09T08:32:41Z
0xA5DF removed the grade
#8 - c4-judge
2024-03-09T09:38:20Z
0xA5DF marked the issue as grade-b