TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: low
Invalid

Minting more than the `MAX_SUPPLY` in `TempleGold::mint()` is possible

Summary

An internal function _canDistribute() invoked within TempleGold::mint() implements flawed logic that allows minting tokens beyond the maximum supply.

Vulnerability Details

TempleGold::mint() invokes the internal function _canDistribute(), which is supposed to control the minted supply.

  • TempleGold::mint()

    function mint() external override onlyArbitrum {
    VestingFactor memory vestingFactorCache = vestingFactor;
    DistributionParams storage distributionParamsCache = distributionParams;
    if (vestingFactorCache.numerator == 0) { revert ITempleGold.MissingParameter(); }
    uint256 mintAmount = _getMintAmount(vestingFactorCache);
    /// @dev no op silently
    if (!_canDistribute(mintAmount)) { return; } // @audit - this line invokes `_canDistribute()`
    lastMintTimestamp = uint32(block.timestamp);
    _distribute(distributionParamsCache, mintAmount);
    }

However, _canDistribute() has flawed logic, particularly in its return statement.

  • _canDistribute()

    function _canDistribute(uint256 mintAmount) private view returns (bool) {
    return mintAmount != 0 && _totalDistributed + mintAmount == MAX_SUPPLY ? true : mintAmount >= MINIMUM_MINT;
    }

The return statement will return true if mintAmount >= MINIMUM_MINT, effectively allowing mint amounts greater than MINIMUM_MINT to bypass the conditions imposed earlier _totalDistributed + mintAmount == MAX_SUPPLY. This is the flaw in the logic.

Now reviewing the code again of TempleGold::mint(), this allows the minting more than the maximum supply via internal function _distribute().

  • TempleGold::mint()

    function mint() external override onlyArbitrum {
    VestingFactor memory vestingFactorCache = vestingFactor;
    DistributionParams storage distributionParamsCache = distributionParams;
    if (vestingFactorCache.numerator == 0) { revert ITempleGold.MissingParameter(); }
    uint256 mintAmount = _getMintAmount(vestingFactorCache);
    /// @dev no op silently
    if (!_canDistribute(mintAmount)) { return; } // @audit - this line invokes `_canDistribute()`
    lastMintTimestamp = uint32(block.timestamp);
    _distribute(distributionParamsCache, mintAmount); // @audit - minting is done in this function
    }

Impact

Minting more than the intended maximum supply can lead to inflationary effects, devaluation, and eventual loss of value.

Tools Used

Manual Review

Recommendations

Make a simple fix in _canDistribute() like this:

function _canDistribute(uint256 mintAmount) private view returns (bool) {
- return mintAmount != 0 && _totalDistributed + mintAmount == MAX_SUPPLY ? true : mintAmount >= MINIMUM_MINT;
+ return mintAmount >= MINIMUM_MINT && _totalDistributed + mintAmount == MAX_SUPPLY ? true : false;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

`_canDistribute` could return a result breaking the MAX TOTAL SUPPLY of TGLD

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.