BaseRewardsGauge

Git Source

Inherits: IBaseRewardsGauge, ERC4626Upgradeable, ERC20PermitUpgradeable, AccessControlEnumerableUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable

Gauge contract for managing and distributing reward tokens to stakers.

This contract handles the accounting of reward tokens, allowing users to claim their accrued rewards. It supports multiple reward tokens and allows for the addition of new rewards by authorized distributors. It does not support rebasing or fee on transfer tokens, or tokens with a max supply greater than type(uint128).max. The total supply of the gauge will always be equal to the total assets held by the gauge.

State Variables

MANAGER_ROLE

Role identifier for the manager role.

bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");

PAUSER_ROLE

Role identifier for the pauser role.

bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

MAX_REWARDS

Maximum number of rewards that can be managed by the gauge.

uint256 public constant MAX_REWARDS = 8;

_WEEK

Constant representing one week in seconds.

uint256 internal constant _WEEK = 1 weeks;

_PRECISION

Precision used for reward calculations.

uint256 internal constant _PRECISION = 1e18;

rewardTokens

Array of reward token addresses.

address[] public rewardTokens;

_rewardData

Mapping from reward token address to its associated reward data.

mapping(address => Reward) internal _rewardData;

rewardsReceiver

Mapping from claimant address to their default reward receiver address.

mapping(address => address) public rewardsReceiver;

rewardIntegralFor

Mapping from reward token address to claimant address to their integral reward amount.

mapping(address => mapping(address => uint256)) public rewardIntegralFor;

claimData

Mapping from user address to reward token address to their claim data (claimable and claimed amounts).

mapping(address => mapping(address => uint256)) public claimData;

Functions

constructor

Constructor that disables initializers to prevent further initialization.

constructor() payable;

__BaseRewardsGauge_init

function __BaseRewardsGauge_init(address asset_) internal onlyInitializing;

decimals

Get the number of decimals for this token.

function decimals() public view override(ERC20Upgradeable, ERC4626Upgradeable) returns (uint8);

Returns

NameTypeDescription
<none>uint8uint8 Number of decimals

claimedReward

Get the number of already-claimed reward tokens for a user

function claimedReward(address addr, address token) external view returns (uint256);

Parameters

NameTypeDescription
addraddressAccount to get reward amount for
tokenaddressToken to get reward amount for

Returns

NameTypeDescription
<none>uint256uint256 Total amount of _token already claimed by _addr

claimableReward

Get the number of claimable reward tokens for a user

function claimableReward(address user, address rewardToken) external view returns (uint256);

Parameters

NameTypeDescription
useraddressAccount to get reward amount for
rewardTokenaddressToken to get reward amount for

Returns

NameTypeDescription
<none>uint256uint256 Claimable reward token amount

getRewardData

Get the reward data for a reward token

function getRewardData(address rewardToken) external view returns (Reward memory);

Parameters

NameTypeDescription
rewardTokenaddresstoken address to get reward data for

Returns

NameTypeDescription
<none>RewardReward struct for the reward token

setRewardsReceiver

Set the default reward receiver for the caller.

When set to address(0), rewards are sent to the caller

function setRewardsReceiver(address receiver) external;

Parameters

NameTypeDescription
receiveraddressReceiver address for any rewards claimed via claimRewards

claimRewards

Claim available reward tokens for addr

function claimRewards(address addr, address receiver) external nonReentrant;

Parameters

NameTypeDescription
addraddressAddress to claim for
receiveraddressAddress to transfer rewards to - if set to address(0), uses the default reward receiver for the caller

addReward

Adds a new reward token to be distributed by this contract.

Adds a new reward token to the contract, enabling it to be claimed by users. Can only be called by an address with the manager role.

function addReward(address rewardToken, address distributor) external onlyRole(MANAGER_ROLE);

Parameters

NameTypeDescription
rewardTokenaddressThe address of the reward token to add.
distributoraddressThe address of the distributor for the reward token.

setRewardDistributor

Set the reward distributor for a reward token. Only the current distributor or an address with the manager role can call this.

function setRewardDistributor(address rewardToken, address distributor) external;

Parameters

NameTypeDescription
rewardTokenaddressaddress of the reward token
distributoraddressaddress of the distributor contract

depositRewardToken

Deposit reward tokens into the gauge. Only the distributor or an address with the manager role can call this.

function depositRewardToken(address rewardToken, uint256 amount) external nonReentrant;

Parameters

NameTypeDescription
rewardTokenaddressaddress of the reward token
amountuint256amount of reward tokens to deposit

pause

Pauses the contract. Only callable by PAUSER_ROLE or DEFAULT_ADMIN_ROLE.

function pause() external;

unpause

Unpauses the contract. Only callable by DEFAULT_ADMIN_ROLE.

function unpause() external onlyRole(DEFAULT_ADMIN_ROLE);

totalAssets

Returns the total amount of the underlying asset that the gauge has.

Provides the total assets managed by the gauge, which is the same as the total supply of the gauge's shares. This is used to calculate the value of each share.

function totalAssets() public view virtual override(ERC4626Upgradeable) returns (uint256);

Returns

NameTypeDescription
<none>uint256The total assets held by the gauge.

_checkpointRewards

Internal function to claim pending rewards and update reward accounting for a user. This function is called during any claim operation and when rewards are deposited. It iterates through all reward tokens to update user rewards and optionally claims them.

function _checkpointRewards(address user, uint256 totalSupply_, bool claim, address receiver) internal;

Parameters

NameTypeDescription
useraddressThe user address to checkpoint rewards for. If set to address(0), only updates the global state.
totalSupply_uint256The current total supply of the staking token.
claimboolIf true, rewards will be transferred to the user or their designated receiver.
receiveraddressThe address to send claimed rewards to. If set to address(0), sends to the user or their default receiver.

_updateReward

The unchecked block is used here because the loop index i is simply incremented in each iteration, ensuring that i will not exceed the length of the array and cause an overflow. Underflow is not a concern as i is initialized to 0 and only incremented.

Internal function to update the reward accounting for a given token. This updates the accumulated reward per token and the timestamp of the last reward update. It is called by _checkpointRewards to ensure the reward state is up to date before any interactions.

function _updateReward(address token, uint256 totalSupply_) internal;

Parameters

NameTypeDescription
tokenaddressThe address of the reward token to update accounting for.
totalSupply_uint256The current total supply of the staking token, used to calculate the rewards per token.

_processUserReward

Internal function to process user rewards, updating the claimable and claimed amounts.

function _processUserReward(address token, address user, uint256 userBalance, bool claim, address receiver) internal;

Parameters

NameTypeDescription
tokenaddressThe address of the reward token to process.
useraddressThe user address to process rewards for.
userBalanceuint256The current balance of the user.
claimboolWhether to claim the rewards (transfer them to the user).
receiveraddressThe address to send claimed rewards to.

maxMint

Returns the maximum amount of shares that can be minted. Returns 0 if the contract is paused.

It is possible for totalClaimed + totalClaimable to overflow if using reward tokens with a max supply greater than type(uint128).max. An overflow in the claimed amount of reward tokens could allow a user to withdraw more tokens than allocated, leading to a potential drain of the contract. This can technically happen even if the supply is lower than 2**128 since tokens can be eventually recycled into the rewards, but should be a extremely rare scenario.

Assumes the total supply is equal to the total assets held by the gauge.

function maxMint(address) public view virtual override(ERC4626Upgradeable) returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum amount of shares that can be minted.

maxDeposit

Returns the maximum amount of assets that can be deposited. Returns 0 if the contract is paused.

Assumes the total supply is equal to the total assets held by the gauge.

function maxDeposit(address) public view virtual override(ERC4626Upgradeable) returns (uint256);

Returns

NameTypeDescription
<none>uint256The maximum amount of assets that can be deposited.

_beforeTokenTransfer

Hook that is called before any transfer of tokens. This includes minting and burning.

function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20Upgradeable);

Parameters

NameTypeDescription
fromaddressThe address which is transferring tokens.
toaddressThe address which is receiving tokens.
amountuint256The amount of tokens being transferred.

Events

RewardTokenAdded

Event emitted when a reward token is added to the gauge.

event RewardTokenAdded(address indexed rewardToken, address distributor);

Parameters

NameTypeDescription
rewardTokenaddressThe address of the reward token that was added.
distributoraddressThe address of the distributor for the added reward token.

RewardTokenDeposited

Event emitted when a reward token is deposited into the gauge.

event RewardTokenDeposited(address indexed rewardToken, uint256 amount, uint256 newRate, uint256 timestamp);

Parameters

NameTypeDescription
rewardTokenaddressThe address of the reward token that was deposited.
amountuint256The amount of the reward token that was deposited.
newRateuint256The new rate of distribution per second for the deposited reward token.
timestampuint256The timestamp when the deposit occurred.

RewardDistributorSet

Event emitted when a reward distributor is set for a reward token.

event RewardDistributorSet(address indexed rewardToken, address distributor);

Parameters

NameTypeDescription
rewardTokenaddressThe address of the reward token for which the distributor is set.
distributoraddressThe address of the distributor set for the reward token.

Errors

CannotRedirectForAnotherUser

Error indicating an attempt to redirect rewards for another user.

error CannotRedirectForAnotherUser();

MaxRewardsReached

Error indicating that the maximum number of rewards has been reached.

error MaxRewardsReached();

RewardTokenAlreadyAdded

Error indicating that the reward token has already been added.

error RewardTokenAlreadyAdded();

Unauthorized

Error indicating an unauthorized action was attempted.

error Unauthorized();

InvalidDistributorAddress

Error indicating that an invalid distributor address was provided.

error InvalidDistributorAddress();

RewardAmountTooLow

Error indicating that the reward amount is too low.

error RewardAmountTooLow();

ZeroAddress

Error indicating that a zero address was provided where it is not allowed.

error ZeroAddress();

RewardCannotBeAsset

Error indicating that the reward token cannot be the same as the asset token.

error RewardCannotBeAsset();

RewardTokenNotAdded

Error indication that the reward token has not been added.

error RewardTokenNotAdded();

Structs

Reward

struct Reward {
    address distributor;
    uint256 periodFinish;
    uint256 rate;
    uint256 lastUpdate;
    uint256 integral;
    uint256 leftOver;
}