31222 - [SC - Critical] Unlimited Flux minting

Submitted on May 15th 2024 at 04:01:45 UTC by @Tapir49939 for Boost | Alchemix

Report ID: #31222

Report type: Smart Contract

Report severity: Critical

Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/Voter.sol

Impacts:

  • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

  • Manipulation of governance voting result deviating from voted outcome and resulting in a direct change from intended effect of original results

Description

Vulnerability Details

The attacker can mint unlimited amount of Flux tokens.

The vote and reset functions of the Voter contract could be called only once in an Epoch. Therefore, the amount of Flux tokens minted is limited.

function reset(uint256 _tokenId) public onlyNewEpoch(_tokenId) {
    if (msg.sender != admin) {
        require(IVotingEscrow(veALCX).isApprovedOrOwner(msg.sender, _tokenId), "not approved or owner");
    }

    lastVoted[_tokenId] = block.timestamp;
    _reset(_tokenId);
    IVotingEscrow(veALCX).abstain(_tokenId);
    IFluxToken(FLUX).accrueFlux(_tokenId);  // Accrue Flux once in an Epoch, onlyNewEpoch modifier enforces this!
}

However, the poke function lacks such limitations and onlyNewEpoch modifier, and could be called any number of times. Poke calls _vote internal functions that accrues Flux.

The attack scenario is simple:

  1. Vote for a pool.

  2. Keep calling poke in a loop, Flux will be minted.

Impact Details

Consequences are dire:

  1. Flux token has a market value.

  2. Flux token could be used to boost the voting power.

Proof of Concept

Run the test as: forge test --mp src/test/Boost.t.sol --fork-url 'https://...' -vv

Output:

Last updated

Was this helpful?