Skip to content

RewardVault

 | ABI JSON

Git Source

Inherits: PausableUpgradeable, ReentrancyGuardUpgradeable, FactoryOwnable, StakingRewards, IRewardVault

Author: Berachain Team

This contract is the vault for the Berachain rewards, it handles the staking and rewards accounting of BGT.

This contract is taken from the stable and tested: https://github.com/Synthetixio/synthetix/blob/develop/contracts/StakingRewards.sol We are using this model instead of 4626 because we want to incentivize staying in the vault for x period of time to to be considered a 'miner' and not a 'trader'.

State Variables

MAX_INCENTIVE_RATE

solidity
uint256 private constant MAX_INCENTIVE_RATE = 1e36;

SAFE_GAS_LIMIT

solidity
uint256 private constant SAFE_GAS_LIMIT = 500_000;

MIN_REWARD_DURATION

The minimum reward duration.

solidity
uint256 public constant MIN_REWARD_DURATION = 3 days;

MAX_REWARD_DURATION

The maximum reward duration.

solidity
uint256 public constant MAX_REWARD_DURATION = 7 days;

maxIncentiveTokensCount

The maximum count of incentive tokens that can be stored.

solidity
uint8 public maxIncentiveTokensCount;

distributor

The address of the distributor contract.

solidity
address public distributor;

beaconDepositContract

The BeaconDeposit contract.

solidity
IBeaconDeposit public beaconDepositContract;

_delegateStake

solidity
mapping(address account => DelegateStake) internal _delegateStake;

_operators

The mapping of accounts to their operators.

solidity
mapping(address account => address operator) internal _operators;

incentives

the mapping of incentive token to its incentive data.

solidity
mapping(address token => Incentive) public incentives;

whitelistedTokens

The list of whitelisted tokens.

solidity
address[] public whitelistedTokens;

rewardVaultManager

The address authorized to manage reward vault operations and configurations.

This role is typically assigned to dApp teams to enable them to configure reward distribution parameters.

solidity
address public rewardVaultManager;

_lastRewardDurationChangeTimestamp

solidity
uint256 private _lastRewardDurationChangeTimestamp;

targetRewardsPerSecond

The target rewards per second, scaled by PRECISION.

This acts as both a maximum and a target rate. When the calculated reward rate exceeds this value, the duration is dynamically adjusted to achieve this target rate, but never goes below MIN_REWARD_DURATION. This prevents the issue where a spike in rewards would permanently expand the duration, causing subsequent smaller rewards to be spread over longer periods with very low rates.

solidity
uint256 public targetRewardsPerSecond;

pendingRewardsDuration

The pending rewards duration.

Comes into effect during the next notifyRewardAmount call.

solidity
uint256 public pendingRewardsDuration;

minRewardDurationForTargetRate

The reward duration in case targetRewardsPerSecond is not met.

must be between MIN_REWARD_DURATION and MAX_REWARD_DURATION and can be set only by reward vault manager.

solidity
uint256 public minRewardDurationForTargetRate;

Functions

constructor

Note: oz-upgrades-unsafe-allow: constructor

solidity
constructor();

initialize

Initialize the vault, this is only callable once and by the factory since its the deployer.

solidity
function initialize(
    address _beaconDepositContract,
    address _bgt,
    address _distributor,
    address _stakingToken
)
    external
    initializer;

Parameters

NameTypeDescription
_beaconDepositContractaddress
_bgtaddressThe address of the BGT token.
_distributoraddressThe address of the distributor.
_stakingTokenaddressThe address of the staking token.

onlyDistributor

solidity
modifier onlyDistributor();

onlyOperatorOrUser

solidity
modifier onlyOperatorOrUser(address account);

checkSelfStakedBalance

solidity
modifier checkSelfStakedBalance(address account, uint256 amount);

onlyWhitelistedToken

solidity
modifier onlyWhitelistedToken(address token);

onlyRewardVaultManager

solidity
modifier onlyRewardVaultManager();

setDistributor

Allows the factory owner to set the contract that is allowed to distribute rewards.

solidity
function setDistributor(address _rewardDistribution) external onlyFactoryOwner;

Parameters

NameTypeDescription
_rewardDistributionaddressThe address that is allowed to distribute rewards.

notifyRewardAmount

Allows the distributor to notify the reward amount.

solidity
function notifyRewardAmount(bytes calldata pubkey, uint256 reward) external onlyDistributor;

Parameters

NameTypeDescription
pubkeybytesThe pubkey of the validator.
rewarduint256The amount of reward to notify.

recoverERC20

Allows the factory owner to recover any ERC20 token from the vault.

solidity
function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyFactoryOwner;

Parameters

NameTypeDescription
tokenAddressaddressThe address of the token to recover.
tokenAmountuint256The amount of token to recover.

setRewardsDuration

Allows the reward vault manager to update the duration of the rewards.

Only allowed if targetRewardsPerSecond is not set.

solidity
function setRewardsDuration(uint256 _rewardsDuration) external onlyRewardVaultManager;

Parameters

NameTypeDescription
_rewardsDurationuint256The new duration of the rewards.

setTargetRewardsPerSecond

Sets the target rewards per second rate.

This rate acts as both a maximum and a target. When rewards exceed this rate, the duration is dynamically adjusted to achieve this target rate while respecting MIN_REWARD_DURATION constraints. This prevents permanent duration expansion from reward spikes that would cause subsequent smaller rewards to be distributed at very low rates.

solidity
function setTargetRewardsPerSecond(uint256 _targetRewardsPerSecond) external onlyRewardVaultManager;

Parameters

NameTypeDescription
_targetRewardsPerSeconduint256The new target rewards per second, scaled by PRECISION.

setMinRewardDurationForTargetRate

Allows the reward vault manager to set the min reward duration for target rate.

This duration is used in case target rewards per second is not met.

solidity
function setMinRewardDurationForTargetRate(uint256 _minRewardDurationForTargetRate) external onlyRewardVaultManager;

Parameters

NameTypeDescription
_minRewardDurationForTargetRateuint256The new min reward duration for target rate.

whitelistIncentiveToken

Allows the factory owner to whitelist a token to incentivize with.

solidity
function whitelistIncentiveToken(address token, uint256 minIncentiveRate, address manager) external onlyFactoryOwner;

Parameters

NameTypeDescription
tokenaddressThe address of the token to whitelist.
minIncentiveRateuint256The minimum amount of the token to incentivize per BGT emission.
manageraddressThe address of the manager that can addIncentive for this token.

removeIncentiveToken

Allows the factory vault manager to remove a whitelisted incentive token.

solidity
function removeIncentiveToken(address token) external onlyFactoryVaultManager onlyWhitelistedToken(token);

Parameters

NameTypeDescription
tokenaddressThe address of the token to remove.

updateIncentiveManager

Update the manager of an incentive token.

Permissioned function, only allow factory owner to update the manager.

solidity
function updateIncentiveManager(
    address token,
    address newManager
)
    external
    onlyFactoryOwner
    onlyWhitelistedToken(token);

Parameters

NameTypeDescription
tokenaddressThe address of the incentive token.
newManageraddressThe new manager of the incentive token.

setMaxIncentiveTokensCount

Allows the factory owner to update the maxIncentiveTokensCount.

solidity
function setMaxIncentiveTokensCount(uint8 _maxIncentiveTokensCount) external onlyFactoryOwner;

Parameters

NameTypeDescription
_maxIncentiveTokensCountuint8The new maxIncentiveTokens count.

pause

Allows the factory vault pauser to pause the vault.

solidity
function pause() external onlyFactoryVaultPauser;

unpause

Allows the factory vault manager to unpause the vault.

solidity
function unpause() external onlyFactoryVaultManager;

setRewardVaultManager

Allows the factory vault manager to set the address responsible for managing the reward vault.

solidity
function setRewardVaultManager(address _rewardVaultManager) external onlyFactoryVaultManager;

Parameters

NameTypeDescription
_rewardVaultManageraddressThe address of the reward vault manager.

operator

Get the operator for an account.

solidity
function operator(address account) external view returns (address);

Parameters

NameTypeDescription
accountaddressThe account to get the operator for.

Returns

NameTypeDescription
<none>addressThe operator for the account.

getWhitelistedTokensCount

Get the count of active incentive tokens.

solidity
function getWhitelistedTokensCount() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The count of active incentive tokens.

getWhitelistedTokens

Get the list of whitelisted tokens.

solidity
function getWhitelistedTokens() public view returns (address[] memory);

Returns

NameTypeDescription
<none>address[]The list of whitelisted tokens.

getTotalDelegateStaked

Get the total amount staked by delegates.

solidity
function getTotalDelegateStaked(address account) external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount staked by delegates.

getDelegateStake

Get the amount staked by a delegate on behalf of an account.

solidity
function getDelegateStake(address account, address delegate) external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The amount staked by a delegate.

stake

Stake tokens in the vault.

solidity
function stake(uint256 amount) external nonReentrant whenNotPaused;

Parameters

NameTypeDescription
amountuint256The amount of tokens to stake.

delegateStake

Stake tokens on behalf of another account.

solidity
function delegateStake(address account, uint256 amount) external nonReentrant whenNotPaused;

Parameters

NameTypeDescription
accountaddressThe account to stake for.
amountuint256The amount of tokens to stake.

withdraw

Withdraw the staked tokens from the vault.

solidity
function withdraw(uint256 amount) external nonReentrant checkSelfStakedBalance(msg.sender, amount);

Parameters

NameTypeDescription
amountuint256The amount of tokens to withdraw.

delegateWithdraw

Withdraw tokens staked on behalf of another account by the delegate (msg.sender).

solidity
function delegateWithdraw(address account, uint256 amount) external nonReentrant;

Parameters

NameTypeDescription
accountaddressThe account to withdraw for.
amountuint256The amount of tokens to withdraw.

getReward

Claim the reward.

The operator only handles BGT, not STAKING_TOKEN.

solidity
function getReward(
    address account,
    address recipient
)
    external
    nonReentrant
    onlyOperatorOrUser(account)
    returns (uint256);

Parameters

NameTypeDescription
accountaddressThe account to get the reward for.
recipientaddressThe address to send the reward to.

Returns

NameTypeDescription
<none>uint256The amount of the reward claimed.

exit

Exit the vault with the staked tokens and claim the reward.

Only the account holder can call this function, not the operator.

solidity
function exit(address recipient) external nonReentrant;

Parameters

NameTypeDescription
recipientaddressThe address to send the 'BGT' reward to.

setOperator

Allows msg.sender to set another address to claim and manage their rewards.

solidity
function setOperator(address _operator) external;

Parameters

NameTypeDescription
_operatoraddressThe address that will be allowed to claim and manage rewards.

addIncentive

Add an incentive token to the vault.

Permissioned function, only callable by incentive token manager.

solidity
function addIncentive(
    address token,
    uint256 amount,
    uint256 incentiveRate
)
    external
    nonReentrant
    onlyWhitelistedToken(token);

Parameters

NameTypeDescription
tokenaddressThe address of the token to add as an incentive.
amountuint256The amount of the token to add as an incentive.
incentiveRateuint256The amount of the token to incentivize per BGT emission.

PoL Fee Collection

When incentives are distributed, a portion is automatically collected as a fee for BERA stakers:

  • Fee Rate: 33% of the incentive amount
  • Fee Collection: Automatically sent to the Incentive Fee Collector
  • Remaining Amount: The remaining 67% is available for distribution to validators

accountIncentives

Process incentives added via IERC20.transfer, adding them to the incentive accounting.

Permissioned function, only callable by incentive token manager.

solidity
function accountIncentives(address token, uint256 amount) external nonReentrant onlyWhitelistedToken(token);

Parameters

NameTypeDescription
tokenaddressThe address of the token to process.
amountuint256The amount of token to account as incentive.

_checkSelfStakedBalance

Check if the account has enough self-staked balance.

solidity
function _checkSelfStakedBalance(address account, uint256 amount) internal view;

Parameters

NameTypeDescription
accountaddressThe account to check the self-staked balance for.
amountuint256The amount being withdrawn.

_safeTransferRewardToken

The Distributor grants this contract the allowance to transfer the BGT in its balance.

solidity
function _safeTransferRewardToken(address to, uint256 amount) internal override;

_checkRewardSolvency

solidity
function _checkRewardSolvency() internal view override;

_processIncentives

process the incentives for a validator.

If a token transfer consumes more than 500k gas units, the transfer alone will fail.

solidity
function _processIncentives(bytes calldata pubkey, uint256 bgtEmitted) internal;

Parameters

NameTypeDescription
pubkeybytesThe pubkey of the validator to process the incentives for.
bgtEmitteduint256The amount of BGT emitted by the validator.

_deleteWhitelistedTokenFromList

solidity
function _deleteWhitelistedTokenFromList(address token) internal;

_setRewardRate

solidity
function _setRewardRate() internal override;

Structs

DelegateStake

Struct to hold delegate stake data.

solidity
struct DelegateStake {
    uint256 delegateTotalStaked;
    mapping(address delegate => uint256 amount) stakedByDelegate;
}

Properties

NameTypeDescription
delegateTotalStakeduint256The total amount staked by delegates.
stakedByDelegatemapping(address delegate => uint256 amount)The mapping of the amount staked by each delegate.

Incentive

Struct to hold an incentive data.

solidity
struct Incentive {
    uint256 minIncentiveRate;
    uint256 incentiveRate;
    uint256 amountRemaining;
    address manager;
}

Properties

NameTypeDescription
minIncentiveRateuint256The minimum amount of the token to incentivize per BGT emission.
incentiveRateuint256The amount of the token to incentivize per BGT emission.
amountRemaininguint256The amount of the token remaining to incentivize.
manageraddressThe address of the manager that can addIncentive for this incentive token.