TempleGold

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

Inaccurate Token Minting Calculation or DOS Due to Missing Time Scaling in `TempleGold` Contract

Summary

The mint function is responsible for minting tokens based on a vesting factor and the elapsed time since the last minting event. There was an issue identified in the _getMintAmount function where the calculation might not account for the correct time interval, potentially leading to incorrect token minting amounts.

Vulnerability Details

The vulnerability lies in the formula used to calculate mintAmount in _getMintAmount:

To determine the correct approach, let's compare the minting amounts with and without dividing by the number of seconds in a year.

Without Dividing by Seconds in a Year

The original formula:

https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/TempleGold.sol#L248

mintAmount = TempleMath.mulDivRound((block.timestamp - lastMintTimestamp) * (MAX_SUPPLY), vestingFactorCache.numerator, vestingFactorCache.denominator, false);

Using the same values:

  • block.timestamp - _lastMintTimestamp = 3 seconds

  • MAX_SUPPLY = 1,000,000,000

  • vestingFactorCache.numerator = 1

  • vestingFactorCache.denominator = 3

  • Without dividing by seconds in a year: The mint amount is 1,000,000,000 tokens.

With dividing the value with seconds in year

block.timestamp - _lastMintTimestamp = 3 seconds

  • MAX_SUPPLY = 1,000,000,000

  • vestingFactorCache.numerator = 1

  • vestingFactorCache.denominator = 3

  • With dividing by seconds in a year: The mint amount is approximately 31.71 tokens.

// Without dividing by seconds in a year
mintAmount = TempleMath.mulDivRound(
(block.timestamp - _lastMintTimestamp) * MAX_SUPPLY,
vestingFactorCache.numerator,
vestingFactorCache.denominator,
false
);
// With dividing by seconds in a year
mintAmount = TempleMath.mulDivRound(
(block.timestamp - _lastMintTimestamp) * MAX_SUPPLY,
vestingFactorCache.numerator,
vestingFactorCache.denominator * secondsInYear,
false
);

Impact

If the time interval (block.timestamp - _lastMintTimestamp) is not accurately divided by the correct scaling factor (such as seconds in a year), the minting calculation will be inaccurate. This could potentially lead to minting more tokens than intended within a given time period, affecting the overall token supply and potentially violating the maximum supply constraint (MAX_SUPPLY).

And if suppose we mint token for every alternative seconds then, execution will go something like

values:

  • block.timestamp - _lastMintTimestamp = 1 second

  • MAX_SUPPLY = 1,000,000,000

  • vestingFactorCache.numerator = 1

  • vestingFactorCache.denominator = 3

// Without dividing by seconds in a year
mintAmount = TempleMath.mulDivRound(
(block.timestamp - _lastMintTimestamp) * MAX_SUPPLY,
vestingFactorCache.numerator,
vestingFactorCache.denominator,
false
);

Mint Amount= ((1 second)×1,000,000,000×1)​ / 3

approximately 333,333,333.33 tokens

which we consume complete MAX_SUPPLY in in just 3 such type of mints and then DOS will occus due to mint amount more than SUPPLY.

Tools Used

Manual review

Recommendations

change the minting mechansim as shown abive in cin Vulnerabilitysection

// With dividing by seconds in a year
mintAmount = TempleMath.mulDivRound(
(block.timestamp - _lastMintTimestamp) * MAX_SUPPLY,
vestingFactorCache.numerator,
vestingFactorCache.denominator * secondsInYear,
false
);
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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