TempleGold

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

In `TempleGoldStaking` rewards will be not distributed to stakers and they will be stuck

Summary

In TempleGoldStaking rewards will be not distributed because wrong address is passed in notifyDistribution which will always revert and nextRewardAmount would be not updated which is one of the crucial value when it comes to distribution.

Vulnerability Details

If we inspect the notifyDistribution function it looks like this:
https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/TempleGoldStaking.sol#L405C2-L414C6

/**
* @notice Notify rewards distribution. Called by TempleGold contract after successful mint
* @param amount Amount minted to this contract
*/
function notifyDistribution(uint256 amount) external {
if (msg.sender != address(rewardToken)) { revert CommonEventsAndErrors.InvalidAccess(); }
/// @notice Temple Gold contract mints TGLD amount to contract before calling `notifyDistribution`
nextRewardAmount += amount;
emit GoldDistributionNotified(amount, block.timestamp);
}

The issue lies in this check

if (msg.sender != address(rewardToken)) { revert CommonEventsAndErrors.InvalidAccess(); }

The rewardToken address is not TempleGold contract it is ERC20 address

/// @notice Reward token. Temple Gold
IERC20 public immutable override rewardToken;

The actual contract that is calling this function is TempleGold (as it is stated in Nat spec above notifyDistribution also) as we can see here:
https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/TempleGold.sol#L226C1-L231C10

function _distribute(DistributionParams storage params, uint256 mintAmount) private {
uint256 stakingAmount = TempleMath.mulDivRound(params.staking, mintAmount, DISTRIBUTION_DIVISOR, false);
if (stakingAmount > 0) {
_mint(address(staking), stakingAmount);
staking.notifyDistribution(stakingAmount);
}
.
.
.

Since Temple Gold contract will mint TGLD tokens to Temple Gold Staking contract before calling notifyDistribution (as stated and described in the notifyDistribution function ) the tokens will be sent to the TempleGoldStaking contract but would be not aware of that because notifyDistribution will always revert and nextRewardAmount would not be updated so they would be stuck and not distributed to the stakers.

The functions that rely on nextRewardAmount are :

Impact

The reward tokens would be stuck in the contract, they will be not distributed and the accounting of the contract would be inaccurate which will make it's users (stakers) not receive their promised rewards and lose incentive for staking and possible trust and reliability of the protocol.

Tools Used

Manual Review.

Recommendations

Make sure the msg.sender in notifyDistribution is actual temple gold address like this :

/// @notice Store next reward amount for next epoch
uint256 public override nextRewardAmount;
+ /// @notice Temple GOLD address
+ ITempleGold public immutable override templeGold;
function notifyDistribution(uint256 amount) external {
- if (msg.sender != address(rewardToken)) { revert CommonEventsAndErrors.InvalidAccess(); }
+ if (msg.sender != address(templeGold)) { revert CommonEventsAndErrors.InvalidAccess(); }
/// @notice Temple Gold contract mints TGLD amount to contract before calling `notifyDistribution`
nextRewardAmount += amount;
emit GoldDistributionNotified(amount, block.timestamp);
}

As we can see the correct implementation in DaiGoldAuction.
https://github.com/Cyfrin/2024-07-templegold/blob/57a3e597e9199f9e9e0c26aab2123332eb19cc28/protocol/contracts/templegold/DaiGoldAuction.sol#L171

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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