#  Distribution can be bricked, and double claims by a few holders are possible when owner calls LiquidInfrastructureERC20::setDistributableERC20s

Changing distributableERC20s array length without resetting erc20EntitlementPerUnit causes index-out-of-bounds revert in distribute(), bricking rewards and enabling frontrun double-claims.

- Payout: Contest reward
- Severity: medium
- Program: Althea Liquid Infrastructure
- Credited: nuthan2x
- Disclosed: 2024-04-08
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-02-althea-liquid-infrastructure-findings/issues/87
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-althea-liquid-infrastructure%3AM-03
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:business-logic vuln:dos vuln:reward-distribution

**Target:** LiquidInfrastructureERC20 distribution contract
**Root cause:** setDistributableERC20s replaces the distributableERC20s array but does not reset erc20EntitlementPerUnit, so distribute() iterates the new longer array against the stale shorter entitlement array, reverting out of bounds.
**Steps:**
1. Deploy LiquidInfrastructureERC20 with distributableERC20s=[DAI] and two approved holders.
2. Fund contract with DAI and USDC; advance past minDistributionPeriod.
3. Attacker frontruns owner's setDistributableERC20s([DAI,USDC]) by calling `distribute(1)` to distribute old tokens to one holder.
4. Owner tx executes, expanding distributableERC20s to length 2 while erc20EntitlementPerUnit stays length 1.
5. Next `distribute(1)` reverts `Index out of bounds` at `erc20EntitlementPerUnit[j]` for j=1, bricking distribution.
**How found:** Code reading of distribute() loop indexing erc20EntitlementPerUnit by distributableERC20s index, noticing setDistributableERC20s changes array length without recomputing entitlements; confirmed with Foundry PoC.
**Exploitation:** A holder frontruns the owner's setDistributableERC20s call with distribute() to capture old-token rewards for a subset of holders, then backruns to distribute again after the array change, receiving new-token rewards too; the stale entitlement array also permanently reverts distribution until fixed.
**Escalation:** Frontrun/backrun sandwich around an owner config tx to double-claim and DoS further distributions.
**Insight:** When a config setter changes an array that a distribution loop indexes in parallel with a cached per-unit entitlement array, check whether the two arrays can desynchronize in length; frontrunning the setter can capture old-round rewards and brick the next round.
