Althea Liquid Infrastructure - miaowu's results

Liquid Infrastructure.

General Information

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

Althea

Findings Distribution

Researcher Performance

Rank: 73/84

Findings: 1

Award: $7.18

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/main/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L127-L144

Vulnerability details

Any user can cause DOS by transferring to users in the _approvedHolders array, making the contract unable to distribute rewards

Impact

Any user can transfer 0 amount to the user in the _approvedHolders array unlimited times, so that the user can be copied into the holders array unlimited times through holders.push(to) in the _beforeTokenTransfer function. At this time, the transfer will be reverted because the amount of distributed rewards is insufficient to cover these additional accounts being copied. And the function of distributing rewards within the contract is implemented through distribute, which means that all functions of distributing rewards within the contract will be invalid.

Proof of Concept

holders.push(to) This statement will push the transfer target account to the holders array when the balance is 0. As long as the transfer amount is 0, the address can be copied unlimited times.

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); //here!!! }
function distribute(uint256 numDistributions) public nonReentrant { // ... uint i; for (i = nextDistributionRecipient; i < limit; i++) { address recipient = holders[i]; if (isApprovedHolder(recipient)) { uint256[] memory receipts = new uint256[]( distributableERC20s.length ); 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; } } emit Distribution(recipient, distributableERC20s, receipts); } } // ... }

Tools Used

Manual review

Check the holders array and remove duplicate addresses

Assessed type

DoS

#0 - c4-pre-sort

2024-02-22T05:35:50Z

0xRobocop marked the issue as duplicate of #77

#1 - c4-judge

2024-03-04T13:22:40Z

0xA5DF marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter