Althea Liquid Infrastructure - Topmark'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: 41/84

Findings: 1

Award: $60.42

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

60.4187 USDC - $60.42

Labels

bug
2 (Med Risk)
partial-75
duplicate-703

External Links

Lines of code

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

Vulnerability details

Impact

Entitlement Distribution meant for Unapproved Holders Would be Lost in the LiquidInfrastructureERC20 contract as value recovery is not implemented in this regards.

Proof of Concept

function distribute(uint256 numDistributions) public nonReentrant {
        require(numDistributions > 0, "must process at least 1 distribution");
        if (!LockedForDistribution) {
            require(
                _isPastMinDistributionPeriod(),
                "MinDistributionPeriod not met"
            );
            _beginDistribution();
        }

        uint256 limit = Math.min(
            nextDistributionRecipient + numDistributions,
            holders.length
        );

        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);
            }
        }
 >>>       nextDistributionRecipient = i;

        if (nextDistributionRecipient == holders.length) {
            _endDistribution();
        }
    }

The function above shows how distribution is handled in the LiquidInfrastructureERC20.sol contract, from the first pointer in the code above it can be noted that a check is done to ensure that the holder to be distributed to is indeed approved, after the loop is completed nextDistributionRecipient is updated to "i", the problem is that in situations that a holder is not approved no implementation is done to refund this value to the Althea Protocol instead the function silently just continues, meaning for example if the number of the holders to be distributed to is 40 whether they are all approved or not nextDistributionRecipient will be updated to 40 without putting what happens to the lost values that unapproved holders would have gotten into consideration.

Tools Used

Manual Review

In a situation isApprovedHolder(recipient) returns false, instead of just silently proceeding with the next Holder, Althea Protocol should add an implementation to ensure the entitlement that such holder would have gotten is not completely lost, it should be added and refunded to the Althea Protocol.

Assessed type

Access Control

#0 - c4-pre-sort

2024-02-22T05:26:03Z

0xRobocop marked the issue as duplicate of #126

#1 - c4-judge

2024-03-05T12:18:44Z

0xA5DF marked the issue as duplicate of #703

#2 - c4-judge

2024-03-05T12:20:22Z

0xA5DF marked the issue as partial-75

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