ERC20Staking
import "@thirdweb-dev/contracts/extension/Staking20.sol";
The Staking20 smart contract extension implements ERC20 staking mechanism. With this extension, you can set up a staking contract for holders of your ERC20 tokens. Users can stake their tokens and earn a different set of ERC20 tokens as rewards.
Usage
This is an example smart contract demonstrating how to inherit from this extension and override the functions to add (optional) custom functionality.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@thirdweb-dev/contracts/extension/Staking20.sol";
import "@thirdweb-dev/contracts/eip/interface/IERC20.sol";
import "@thirdweb-dev/contracts/eip/interface/IERC20Metadata.sol";
contract MyContract is Staking20 {
    // ERC20 Reward Token address. See {_mintRewards}.
    address public rewardToken;
    /**
     *  We store the contract deployer's address only for the purposes of the example
     *  in the code comment below.
     *
     *  Doing this is not necessary to use the `Staking20` extension.
     */
    address public deployer;
    constructor(
        uint256 _timeUnit,
        uint256 _rewardRatioNumerator,
        uint256 _rewardRatioDenominator,
        address _stakingToken,
        address _rewardToken,
        address _nativeTokenWrapper
    ) Staking20(
            _nativeTokenWrapper,
            _stakingToken,
            IERC20Metadata(_stakingToken).decimals(),
            IERC20Metadata(_rewardToken).decimals()
    ) {
        _setStakingCondition(_timeUnit, _rewardRatioNumerator, _rewardRatioDenominator);
        rewardToken = _rewardToken;
        deployer = msg.sender;
    }
    /**
     *  @dev    Mint/Transfer ERC20 rewards to the staker. Must override.
     *
     *  @param _staker    Address for sending rewards to.
     *  @param _rewards   Amount of tokens to be given out as reward.
     *
     */
    function _mintRewards(address _staker, uint256 _rewards) internal override {
        IERC20(rewardToken).transfer(_staker, _rewards);
    }
    // Returns whether staking restrictions can be set in given execution context.
    function _canSetStakeConditions() internal view override returns (bool) {
        return msg.sender == deployer;
    }
}
Base Contracts Implementing This Extension
Full API Reference
stake
function stake(uint256 amount) external;
- Lets a user stake a number of ERC20 tokens by passing in amount.
 - Parameter 
amount: Amount of tokens to stake. 
withdraw
function withdraw(uint256 amount) external payable;
- Un-stake and withdraw tokens from the contract.
 - Parameter 
amount: Amount of tokens to withdraw. 
claimRewards
function claimRewards() external;
- Claim accumulated rewards. This claim method allows for a pull mechanism where users must initiate claiming of rewards.
 
getStakeInfo
function getStakeInfo(address staker) external view returns (uint256 tokensStaked, uint256 rewards);
- View number of tokens staked and total rewards available for a user.
 - Parameter 
staker: Account address of staker. 
setRewardRatio
function setRewardRatio(uint256 numerator, uint256 denominator) external
- Allows an authorized account to set reward ratio. Interpreted as (numerator/denominator) rewards per second/per day/etc based on time-unit. For e.g., ratio of 1/20 would mean 1 reward token for every 20 tokens staked.
 - Parameter 
numerator: Reward ratio numerator. - Parameter 
denominator: Reward ratio denominator. 
setTimeUnit
function setTimeUnit(uint256 timeUnit) external;
- Allows an authorized account to set time unit as a number of seconds. For e.g. 1 hour can be set as 3600 seconds - setting the reward frequency as per hour.
 - Parameter 
timeUnit: New time unit.