TempleGold

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

Lack of Mint Cap Enforcement

Summary

There is no explicit check in the mint function to ensure that the total supply of minted tokens does not exceed the MAX_SUPPLY it is defined in the contract.

Vulnerability Details

The attacker repeatedly calls the mint function to mint new tokens. Since the function does not enforce the MAX_SUPPLY limit, the total supply of tokens can exceed the defined MAX_SUPPLY.

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

function mint() external override onlyArbitrum {
VestingFactor memory vestingFactorCache = vestingFactor;
DistributionParams storage distributionParamsCache = distributionParams;
if (vestingFactorCache.numerator == 0) { revert ITempleGold.MissingParameter(); }
uint256 mintAmount = _getMintAmount(vestingFactorCache);
if (!_canDistribute(mintAmount)) { return; }
lastMintTimestamp = uint32(block.timestamp);
_distribute(distributionParamsCache, mintAmount);
}

Invoke the mint Function Repeatedly: Use a script or manually call the mint repeatedly function until the total supply exceeds MAX_SUPPLY.

/ Example script to repeatedly call mint
const templeGold = new ethers.Contract(contractAddress, abi, signer);
async function exploitMint() {
for (let i = 0; i < 1000; i++) {
await templeGold.mint();
console.log(`Mint attempt ${i + 1} complete`);
}
}
exploitMint();

Impact

Exceeding the maximum supply can lead to inflation and devaluation of the token. An attacker or even a well-intentioned user can unintentionally mint more tokens than the MAX_SUPPLY, leading to an overall supply that exceeds the intended cap.

Tools Used

Recommendations

Add a check in the mint function to ensure that the total supply of minted tokens, including the current mintAmount, does not exceed MAX_SUPPLY.

function mint() external override onlyArbitrum {
VestingFactor memory vestingFactorCache = vestingFactor;
DistributionParams storage distributionParamsCache = distributionParams;
if (vestingFactorCache.numerator == 0) { revert ITempleGold.MissingParameter(); }
uint256 mintAmount = _getMintAmount(vestingFactorCache);
// Add a check to ensure the total supply does not exceed MAX_SUPPLY
if (_totalDistributed + mintAmount > MAX_SUPPLY) {
revert ITempleGold.ExceedsMaxSupply();
}
if (!_canDistribute(mintAmount)) { return; }
lastMintTimestamp = uint32(block.timestamp);
_distribute(distributionParamsCache, mintAmount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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