31512 - [SC - Critical] Infinite minting of FLUX through Merge

Submitted on May 20th 2024 at 22:10:34 UTC by @Django for Boost | Alchemix

Report ID: #31512

Report type: Smart Contract

Report severity: Critical

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

Impacts:

  • Theft of unclaimed yield

Description

Brief/Intro

Users are able to claim more FLUX rewards than they should simply by merging their tokens. Since the merge() operation increases the _to token's balance, the _from token can simply increment its unclaimed FLUX through voter.reset() and then merge its balance into _to. Then _to can claim with the increased balance. This operation can continue for as many iterations as desired.

Vulnerability Details

Users increase their unclaimed FLUX balance through voter.reset() for their tokens after an epoch has passed. They can then claim their FLUX by calling FLUX.claimFlux().

However, since the claimableFlux() FLUX balance of each token is taken at the current block.timestamp, a user can simply call votingEscrow.merge() to merge their already claimed tokens with an unclaimed token, increasing its balance and effectively doubling their rewards to claim.

    function claimableFlux(uint256 _tokenId) public view returns (uint256) {
        // If the lock is expired, no flux is claimable at the current epoch
        if (block.timestamp > locked[_tokenId].end) {
            return 0;
        }


        // Amount of flux claimable is <fluxPerVeALCX> percent of the balance
        return (_balanceOfTokenAt(_tokenId, block.timestamp) * fluxPerVeALCX) / BPS;
    }

Impact Details

  • Unauthorized claiming of FLUX rewards

Output from POC

Proof of Concept

Last updated

Was this helpful?