TempleGold

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

Potential Division by Zero Risk in Reward Distribution Minting Process

Summary

`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.

Vulnerability Details

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:**

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FTempleGoldStaking.sol#L180-L194

```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:**

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FTempleGoldStaking.sol#L538-L541

```solidity

function _distributeGold() internal {

/// @dev no op silent fail if nothing to distribute

ITempleGold(address(rewardToken)).mint();

}

```

**Mint Function in TempleGold Contract:**

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FTempleGold.sol#L144-L156

```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:**

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FTempleGold.sol#L248-L260

```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.

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol%2Fcontracts%2Ftemplegold%2FTempleGold.sol#L253

```solidity

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

```

Impact

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.

Tools Used

Manual code review

Recommendations

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);

}

```

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.