Althea Liquid Infrastructure - petro_1912'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: 84/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/tree/main/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L142-L145

Vulnerability details

Impact

An approved holder with zero balance can be added several times to holders, so it can receive rewards several times during a revenue distribution, so by exploiting it, can drain all distributableERC20s from LiquidInfrastructureERC20.

Proof of Concept

_beforeTokenTransfer function doesn't check the amount being received at all, so any account can send 0 tokens to approved holder(which has zero balance), then it can be added in holders though it has zero balance.
_afterTokenTransfer function doesn't check the amount and updated balance of to account too, so it exists in holders.

Attack Scenario A, B = approved holder, C = any account

  1. Approved holder(A) sends his all tokens to another Approved holder(B) to empty his balance.
// in A = Approved Holder
IERC20(liquidInfrastructureERC20).transfer(B, IERC20(liquidInfrastructureERC20).balanceOf(A));
  1. Any EOA(B or, C = another) sends zero token to A, then A can be added into holders array. This process can be repeated as many as possible.
// in EOA (B or C = it doesn't need to be approved holder )
for (uint256 i = 0; i < 1000; i++) {
   IERC20(liquidInfrastructureERC20).transfer(A, 0);
}

then holders can have many A items. but at the moment balance of A is zero, so can not receive a revenue.

// holders = [..., A, A, A, A]
  1. B sends token back to A to receive a revenue.
// in B 
IERC20(liquidInfrastructureERC20).transfer(A, amount);
  1. During distribution, it can receive rewards many times from the contract.

Tools Used

Manual review

Holder with zero balance should not be added to holders and duplication should not be allowed in holders.

function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { require(!LockedForDistribution, "distribution in progress"); + require(amount != 0, "zero amount"); 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) { + bool isInHolder = false; + for (uint i = 0; i < holders.length; i++) { + if (holders[i] == to) { + isInHolder = true; + break; + } + } + if (!isInHolder) + holders.push(to); - holders.push(to); } }

Assessed type

Invalid Validation

#0 - c4-pre-sort

2024-02-20T06:28:34Z

0xRobocop marked the issue as duplicate of #536

#1 - c4-pre-sort

2024-02-20T06:33:33Z

0xRobocop marked the issue as duplicate of #77

#2 - c4-judge

2024-03-04T13:04:37Z

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