Skip to main content

GMD Staking

GMD holders can stake their tokens with the Pool and receive both USDT and GMD rewards. 100% of the fees collected by GMD Exchange are distributed via Pool. Stakers can also take part in Oracle's bounty program.

Staking Pool

Staking Pool is an autonomous smart contract that takes care of staking balance logic. It records and stores on-chain all pool balance changes. It does so by wrapping GMD deposits into non-transferable, non-delegable ERC20Votes, referred to as pool shares.

Rewards Pool

Autonomous smart contract that takes care of linear rewards distribution (Synthetix like). After distribution duration is set, one can only increase the rewards amount that is to be distributed. Once rewards are added to the pool, participants earn yield proportional to their share of Staking Pool and time participating in the distribution. Reward amount can be perpetually increased, whereas distribution duration can only be changed after current pool has expired.


Staking Pool Contract Overview

  • Inherits: vGMD
  • Implements: Staking logic, reward pool management, spender approval, and ERC20 wrapping.
  • Events: Staked, Withdrawn, SpenderApproved, SpenderRevoked

Function Documentation

Constructor

/**
* @dev Initializes the staking pool with the specified ERC20 token.
* @param _token The address of the ERC20 token to be staked.
*/
constructor(address _token) vGMD(IERC20(_token))

Modifiers

/**
* @dev Updates rewards for the specified account before function execution.
* @param _account The account whose rewards are updated.
*/
modifier updateReward(address _account)
/**
* @dev Restricts access to only approved spenders after cooldown.
*/
modifier onlyApproved()

Reward Pool Management

/**
* @dev Adds a new reward pool to the staking pool.
* @param _pool The address of the reward pool contract.
*/
function addRewardPool(address _pool) external onlyOwner
/**
* @dev Returns the list of reward pool addresses.
* @return Array of reward pool addresses.
*/
function rewardPools() external view returns (address[] memory)

Reward Claiming

/**
* @dev Claims all rewards for the caller from all reward pools.
*/
function claimRewards() external virtual
/**
* @dev Claims all rewards for a specified account from all reward pools.
* @param _account The account to claim rewards for.
*/
function claimRewards(address _account) external virtual

Pool Share Transfers

/**
* @dev Transfers pool shares between accounts. Only approved spenders can call.
* @param _from The address to transfer shares from.
* @param _to The address to transfer shares to.
* @param _amount The amount of shares to transfer.
* @return True if transfer succeeded.
*/
function transferShares(address _from, address _to, uint256 _amount) external onlyApproved returns (bool)

Staking & Withdrawal

/**
* @dev Stakes ERC20 tokens and mints pool shares for the sender.
* @param _amount The amount of tokens to stake.
*/
function stake(uint256 _amount) external virtual updateReward(_msgSender())
/**
* @dev Withdraws staked tokens and burns pool shares for the sender.
* @param _amount The amount of tokens to withdraw.
*/
function withdraw(uint256 _amount) external virtual updateReward(_msgSender())

Internal Functions

/**
* @dev Updates rewards for the specified account in all reward pools.
* @param _account The account to update rewards for.
*/
function _updateReward(address _account) internal

Events

event Staked(address indexed user, uint256 amount);
event Withdrawn(address indexed user, uint256 amount, address token);
event SpenderApproved(address spender);
event SpenderRevoked(address spender);

Rewards Pool Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IStakingRewards {
/**
* @dev Returns the address of the staking pool contract.
*/
function stakingPool() external view returns (address);

/**
* @dev Returns the address of the reward token.
*/
function rewardToken() external view returns (address);

/**
* @dev Returns stored rewards earned by the caller.
*
* Does not invoke updateReward.
*/
function rewards() external view returns (uint256);

/**
* @dev Returns stored rewards earned by an _account.
*
* Does not invoke updateReward.
*/
function rewards(address _account) external view returns (uint256);

function updateReward(address _account) external;

/**
* @dev Returns the duration of rewards to be paid out (in seconds).
*/
function duration() external view returns (uint256);

/**
* @dev Returns the timestamp of when the rewards finish.
*/
function finishAt() external view returns (uint256);

/**
* @dev Returns the minimum of last updated time and reward finish time.
*/
function updatedAt() external view returns (uint256);

/**
* @dev Returns the reward to be paid out per second.
*/
function rewardRate() external view returns (uint256);

/**
* @dev Returns the sum of (reward rate * dt * 1e18 / total supply).
*/
function rewardPerToken() external view returns (uint256);

/**
* @dev Returns the last time rewards were applicable.
*/
function lastTimeRewardApplicable() external view returns (uint256);

/**
* @dev Returns current rewards earned by the caller.
*/
function earned() external view returns (uint256);

/**
* @dev Returns current rewards earned by an _account.
*/
function earned(address _account) external view returns (uint256);

/**
* @dev Claims the rewards earned by the caller.
*
* Transfers rewardTokens accrued by the caller to its address.
*
* Emits a {RewardPaid} event.
*/
function claimReward() external;

/**
* @dev Claims the rewards earned by the _account.
*
* Transfers rewardTokens accrued by the _account to its address.
*
* Emits a {RewardPaid} event.
*/
function claimReward(address _account) external;

event RewardAdded(uint256 reward, uint256 totalRewards, uint256 rewardRate);
event RewardPaid(address indexed user, uint256 reward);
}