`distributeRewards` function and the associated minting process in the `TempleGold` contract contains a potential issue where the minting calculation could result in a division by zero error. This issue arises because the `mint` function in the `TempleGold` contract does not check if the `vestingFactor.denominator` is zero before proceeding with the calculation.
The `distributeRewards` function is responsible for distributing rewards to stakers by minting TGLD tokens and notifying the reward amount. The process involves calling the `mint` function of the `TempleGold` contract. However, there is a potential issue in the `mint` function where it only checks if the numerator of the `vestingFactor` is zero, potentially overlooking the denominator. If the denominator is zero, the division operation in `_getMintAmount` would cause a runtime error, disrupting the minting process.
**Distribute Rewards Function:**
```solidity
function distributeRewards() updateReward(address(0), 0) external {
if (distributionStarter != address(0) && msg.sender != distributionStarter) { revert CommonEventsAndErrors.InvalidAccess(); }
if (totalSupply == 0) { revert NoStaker(); }
// Mint and distribute TGLD if no cooldown set
if (lastRewardNotificationTimestamp + rewardDistributionCoolDown > block.timestamp) { revert CannotDistribute(); }
_distributeGold();
uint256 rewardAmount = nextRewardAmount;
// revert if next reward is 0 or less than reward duration (final dust amounts)
if (rewardAmount < rewardDuration ) { revert CommonEventsAndErrors.ExpectedNonZero(); }
nextRewardAmount = 0;
_notifyReward(rewardAmount);
lastRewardNotificationTimestamp = uint32(block.timestamp);
}
```
**Distribute Gold Function:**
```solidity
function _distributeGold() internal {
/// @dev no op silent fail if nothing to distribute
ITempleGold(address(rewardToken)).mint();
}
```
**Mint Function in TempleGold Contract:**
```solidity
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; }
lastMintTimestamp = uint32(block.timestamp);
_distribute(distributionParamsCache, mintAmount);
}
```
**Get Mint Amount Function:**
```solidity
function _getMintAmount(VestingFactor memory vestingFactorCache) private view returns (uint256 mintAmount) {
uint32 _lastMintTimestamp = lastMintTimestamp;
uint256 totalSupplyCache = _totalDistributed;
/// @dev if vesting factor is not set, return 0. `_lastMintTimestamp` is set when vesting factor is set
if (_lastMintTimestamp == 0) { return 0; }
mintAmount = TempleMath.mulDivRound((block.timestamp - _lastMintTimestamp) * (MAX_SUPPLY), vestingFactorCache.numerator, vestingFactorCache.denominator, false);
if (totalSupplyCache + mintAmount > MAX_SUPPLY) {
unchecked {
mintAmount = MAX_SUPPLY - totalSupplyCache;
}
}
}
```
Division by zero of denominator is not set and zero not checked.
```solidity
TempleMath.mulDivRound((block.timestamp - _lastMintTimestamp) * (MAX_SUPPLY), vestingFactorCache.numerator, vestingFactorCache.denominator, false);
```
The impact of this vulnerability is that it can cause the `mint` function to fail due to a division by zero error, which would prevent the minting of new TGLD tokens and disrupt the normal operation of the reward distribution process. This could result in stakers not receiving their expected rewards.
Manual code review
ensure that both the numerator and denominator of the `vestingFactor` are non-zero before proceeding with the minting calculation.
```solidity
function mint() external override onlyArbitrum {
VestingFactor memory vestingFactorCache = vestingFactor;
DistributionParams storage distributionParamsCache = distributionParams;
if (vestingFactorCache.numerator == 0 || vestingFactorCache.denominator == 0) {
revert ITempleGold.MissingParameter();
}
uint256 mintAmount = _getMintAmount(vestingFactorCache);
/// @dev no op silently
if (!_canDistribute(mintAmount)) { return; }
lastMintTimestamp = uint32(block.timestamp);
_distribute(distributionParamsCache, mintAmount);
}
```
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.