TempleGold

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

Temple gold staking vesting mechanic bricks rewards inside the contract

Summary

TempleGoldStaking vesting mechanic locks tokens in the contract.

Vulnerability Details

TempleGold mints rewards to three modules. One of them is TempleGoldStaking, where on _distributeGold being triggered, TempleGold will mint tokens, invoke notifyDistribution, and increase nextRewardAmount. In short, TempleGoldStaking receives tokens and accounts them inside nextRewardAmount.

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L409

function notifyDistribution(uint256 amount) external {
if (msg.sender != address(rewardToken)) { revert CommonEventsAndErrors.InvalidAccess(); }
nextRewardAmount += amount;
emit GoldDistributionNotified(amount, block.timestamp);
}

When a new epoch is started, this amount is calculated with rewardDuration to make rewardRate:

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L515

function _notifyReward(uint256 amount) private {
if (block.timestamp >= rewardData.periodFinish) {
rewardData.rewardRate = uint216(amount / rewardDuration);
nextRewardAmount = amount - (rewardData.rewardRate * rewardDuration);

The issue we face is that this math doesn't account for the fact that _earned will distribute only a portion of the reward if the user is vesting.

https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L476

} else {
_perTokenReward = _rewardPerToken() * vestingRate / 1e18;
}

In cases where users are vesting, the contract will allocate X tokens to them, but they will only claim X - Y tokens, as their vest lowers their reward. TempleGoldStaking still accounts this amount in its internal accounting; however, the tokens will remain stuck inside the contract.

Example:

Prerequisites Values
Users 10
Staked tokens 1000
Reward per week 1 per 10 tokens staked (100)
Vesting duration 2 weeks

In our case, User10 has just staked, and the rest of the users have fully vested their stakes.

  1. After 1 week, the epoch will distribute 100 tokens.

  2. Each staker claims 10 as each owns 10% of the shares.

  3. User10 claims 5 tokens as his vesting is 50% done.

  4. 5 tokens remain stuck inside the contract, as everyone has claimed and their rewards are synced.

Impact

Loss of funds.

Tools Used

Manual review

Recommendations

Consider changing the math inside _earned or somehow distribute the rest of the tokens to the contract or the team gnosis.

Updates

Lead Judging Commences

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

Appeal created

pyro Submitter
11 months ago
inallhonesty Lead Judge
11 months ago
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.