BaseRewardsGauge
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
Name | Type | Description |
---|---|---|
<none> | uint8 | uint8 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
Name | Type | Description |
---|---|---|
addr | address | Account to get reward amount for |
token | address | Token to get reward amount for |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 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
Name | Type | Description |
---|---|---|
user | address | Account to get reward amount for |
rewardToken | address | Token to get reward amount for |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 Claimable reward token amount |
getRewardData
Get the reward data for a reward token
function getRewardData(address rewardToken) external view returns (Reward memory);
Parameters
Name | Type | Description |
---|---|---|
rewardToken | address | token address to get reward data for |
Returns
Name | Type | Description |
---|---|---|
<none> | Reward | Reward 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
Name | Type | Description |
---|---|---|
receiver | address | Receiver address for any rewards claimed via claimRewards |
claimRewards
Claim available reward tokens for addr
function claimRewards(address addr, address receiver) external nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
addr | address | Address to claim for |
receiver | address | Address 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
Name | Type | Description |
---|---|---|
rewardToken | address | The address of the reward token to add. |
distributor | address | The 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
Name | Type | Description |
---|---|---|
rewardToken | address | address of the reward token |
distributor | address | address 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
Name | Type | Description |
---|---|---|
rewardToken | address | address of the reward token |
amount | uint256 | amount 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
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
user | address | The user address to checkpoint rewards for. If set to address(0), only updates the global state. |
totalSupply_ | uint256 | The current total supply of the staking token. |
claim | bool | If true, rewards will be transferred to the user or their designated receiver. |
receiver | address | The 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
Name | Type | Description |
---|---|---|
token | address | The address of the reward token to update accounting for. |
totalSupply_ | uint256 | The 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
Name | Type | Description |
---|---|---|
token | address | The address of the reward token to process. |
user | address | The user address to process rewards for. |
userBalance | uint256 | The current balance of the user. |
claim | bool | Whether to claim the rewards (transfer them to the user). |
receiver | address | The 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
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
<none> | uint256 | The 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
Name | Type | Description |
---|---|---|
from | address | The address which is transferring tokens. |
to | address | The address which is receiving tokens. |
amount | uint256 | The 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
Name | Type | Description |
---|---|---|
rewardToken | address | The address of the reward token that was added. |
distributor | address | The 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
Name | Type | Description |
---|---|---|
rewardToken | address | The address of the reward token that was deposited. |
amount | uint256 | The amount of the reward token that was deposited. |
newRate | uint256 | The new rate of distribution per second for the deposited reward token. |
timestamp | uint256 | The 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
Name | Type | Description |
---|---|---|
rewardToken | address | The address of the reward token for which the distributor is set. |
distributor | address | The 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;
}