31461 - [SC - Critical] veALCX holder can mint Unlimited FLUX tokens

Submitted on May 19th 2024 at 21:51:12 UTC by @OxAnmol for Boost | Alchemix

Report ID: #31461

Report type: Smart Contract

Report severity: Critical

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

Impacts:

  • Protocol insolvency

Description

Brief/Intro

Voter:poke function can be called multiple times by the veALCX holder and mint unlimited flux.

Vulnerability Details

The Voter:poke function is used to vote again with the same weights, effectively renewing the previous vote.

https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/Voter.sol#L195C3-L212C6

    function poke(uint256 _tokenId) public {
        // Previous boost will be taken into account with weights being pulled from the votes mapping
        uint256 _boost = 0;

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

        address[] memory _poolVote = poolVote[_tokenId];
        uint256 _poolCnt = _poolVote.length;
        uint256[] memory _weights = new uint256[](_poolCnt);

        for (uint256 i = 0; i < _poolCnt; i++) {
            _weights[i] = votes[_tokenId][_poolVote[i]];
        }

        _vote(_tokenId, _poolVote, _weights, _boost);
    }

It internally calls _vote functions which is responsible for voting by looping though the provided gauge addresses and it also accrues the flux token for voters by calling Flux:accrueFlux.

https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/Voter.sol#L412C4-L455C6

If a user has locked their BPT but has never voted, they can call the poke function. This function attempts to renew the user's voting, but because the user never voted in the first place there is nothing to renew, it only accrues the flux for the user. The user can call this poke function as often as they want to accumulate unlimited flux.

Impact Details

Users can mint an unlimited amount of FLUX, which could potentially devalue the currency and undermine the logic for boosting and early unlocks.

The FLUX token is a vital component of the system and is expected to hold some tangible value in the open market. Unlimited minting could potentially disrupt its tokenomics and make the protocol's DAO insolvent.

Imagine if such an attack occurs one year after the protocol launch. Users holding millions of dollars worth of FLUX could lose everything due to a price surge.

Based on above stated reason I believe this to be a critical issue.

References

https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/Voter.sol#L195C3-L212C6

https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/FluxToken.sol#L188C3-L192C6

Proof of Concept

Here is a simple test to show how veALCX holder can call Voter::poke many times and accrue unlimited flux.

paste the test in FluxTokenTest.t.sol and run it.

Output

Here you can see 98.839805301052500300 FLUX is stolen just by calling the poke function 100 times.

Last updated

Was this helpful?