DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Centralized Reward Distribution Dependency in `FjordStaking::addReward`

Description

The FjordStaking::addReward function is responsible for adding rewards to the staking pool, which are distributed to users based on their staked amounts. This function must be called manually by the rewardAdmin at the beginning and end of each epoch. If the rewardAdmin fails to call addReward in a timely manner, rewards for stakers may not be funded for that epoch, leading to missed reward distributions.

This introduces a single point of failure, where the continuous operation and proper reward distribution of the staking contract is dependent on a single actor (the rewardAdmin). If the rewardAdmin forgets or is unable to perform this action, it could lead to disruptions in the reward distribution, undermining the contract's intended incentives.

Impact

  • Unfunded Reward Epochs: Stakers might not receive their expected rewards if the rewardAdmin fails to call FjordStaking::addReward, leading to dissatisfaction among users and disruption of functionality.

  • Centralization Risk: The staking contract's reliance on a single entity introduces a centralization risk, which is contrary to the principles of decentralized finance (DeFi).

  • Operational Risk: If the rewardAdmin becomes inactive or is otherwise unable to perform their duties, the contract's reward distribution could cease, affecting the overall functionality of the staking mechanism.

Current Implementation

The FjordStaking::addReward function is currently implemented as follows:

/// @notice addReward should be called by master chef
/// must be only call if it's can trigger update next epoch so the total staked won't increase anymore
/// must be the action to trigger update epoch and the last action of the epoch
/// @param _amount The amount of tokens to be added as rewards.
function addReward(uint256 _amount) external onlyRewardAdmin {
//CHECK
if (_amount == 0) revert InvalidAmount();
//EFFECT
uint16 previousEpoch = currentEpoch;
//INTERACT
fjordToken.safeTransferFrom(msg.sender, address(this), _amount);
_checkEpochRollover();
emit RewardAdded(previousEpoch, msg.sender, _amount);
}

In this implementation, the contract relies on the rewardAdmin to call this function manually at the appropriate time. If this function is not called, no new rewards will be added to the staking pool for the next epoch, resulting in unfunded rewards for stakers.

Medium Severity

  • If the rewardAdmin is a highly trusted entity with robust operational processes in place, the likelihood of failing to call addReward is lower. However, the reliance on manual intervention still presents a risk, especially if the protocol grows or the responsibilities of the rewardAdmin change over time.

  • Justification: The potential impact is significant (stakers missing rewards), but the likelihood of occurrence is lower if the rewardAdmin is diligent. Therefore, this is classified as a medium finding.

Recommended Mitigation

  1. Automate Reward Distribution: Implement an automated mechanism, such as Chainlink Keepers or Gelato Network, to call FjordStaking::addReward at the end of each epoch. This would reduce the reliance on manual intervention and ensure timely reward distribution.

  2. Introduce Fallback Mechanisms: Allow other trusted addresses, or even a decentralized governance mechanism, to call FjordStaking::addReward in the event that the rewardAdmin is unable or fails to do so.

  3. Dynamic Reward Allocation: Consider implementing a system where rewards are automatically calculated based on the available balance in the contract at each epoch rollover. This would eliminate the need for manual reward funding altogether.

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.