Exploring the StakingRewards Contract on BitTorrent Chain (BTTC)

Alvin Lang
Sep 26, 2024 10:31

Discover the functionalities of the StakingRewards contract on BTTC, enabling token staking and rewards. Dive into its key components, including state variables, events, and functions.

Exploring the StakingRewards Contract on BitTorrent Chain (BTTC)

The StakingRewards contract on the BitTorrent Chain (BTTC) offers users the opportunity to stake tokens and earn rewards, providing a decentralized and automated mechanism for incentivizing participation, according to BitTorrent Inc..

The StakingRewards Contract: Your Gateway to Passive Income

The StakingRewards contract enables users to stake their tokens and earn rewards over a specified period. This smart contract is designed to create incentive mechanisms and encourage long-term participation in the BTTC token ecosystem.

State Variables and Structs: The Foundation

IERC20 public immutable stakingToken;
IERC20 public immutable rewardsToken;

address public owner;

// Duration of rewards to be paid out (in seconds)
uint public duration;
// Timestamp of when the rewards finish
uint public finishAt;
// Minimum of last updated time and reward finish time
uint public updatedAt;
// Reward to be paid out per second
uint public rewardRate;
// Sum of (reward rate * dt * 1e18 / total supply)
uint public rewardPerTokenStored;
// User address => rewardPerTokenStored
mapping(address => uint) public userRewardPerTokenPaid;
// User address => rewards to be claimed
mapping(address => uint) public rewards;

// Total staked
uint public totalSupply;
// User address => staked amount
mapping(address => uint) public balanceOf;

These variables form the backbone of the contract, defining the staking and reward mechanisms.

Events: Keeping Everyone Informed

Including events in the contract is a good practice for transparency and off-chain tracking. Suggested events include:

event Staked(address indexed user, uint amount);
event Withdrawn(address indexed user, uint amount);
event RewardPaid(address indexed user, uint reward);
event RewardDurationUpdated(uint newDuration);
event RewardNotified(uint amount);

Key Functions: The Heart of Staking and Rewards

Constructor

constructor(address _stakingToken, address _rewardToken) {
owner = msg.sender;
stakingToken = IERC20(_stakingToken);
rewardsToken = IERC20(_rewardToken);
}

The constructor initializes the contract with the addresses of the staking and reward tokens, and sets the contract deployer as the owner.

Modifiers

modifier onlyOwner() {
require(msg.sender == owner, "not authorized");
_;
}
modifier updateReward(address _account) {
rewardPerTokenStored = rewardPerToken();
updatedAt = lastTimeRewardApplicable();

if (_account != address(0)) {
rewards[_account] = earned(_account);
userRewardPerTokenPaid[_account] = rewardPerTokenStored;
}

_;
}

These modifiers ensure that only the owner can perform certain actions and that rewards are updated before any state changes.

Reward Calculation Functions

function lastTimeRewardApplicable() public view returns (uint) {
return _min(finishAt, block.timestamp);
}
function rewardPerToken() public view returns (uint) {
if (totalSupply == 0) {
return rewardPerTokenStored;
}
return
rewardPerTokenStored +
(rewardRate * (lastTimeRewardApplicable() - updatedAt) * 1e18) /
totalSupply;
}

These functions calculate the last time rewards were applicable and the reward rate per token.

Staking and Withdrawing Tokens

function stake(uint _amount) external updateReward(msg.sender) {
require(_amount > 0, "amount = 0");
stakingToken.transferFrom(msg.sender, address(this), _amount);
balanceOf[msg.sender] += _amount;
totalSupply += _amount;
emit Staked(msg.sender, _amount);
}
function withdraw(uint _amount) external updateReward(msg.sender) {
require(_amount > 0, "amount = 0");
balanceOf[msg.sender] -= _amount;
totalSupply -= _amount;
stakingToken.transfer(msg.sender, _amount);
emit Withdrawn(msg.sender, _amount);
}

These functions allow users to stake and withdraw tokens, updating their rewards accordingly.

Earning and Claiming Rewards

function earned(address _account) public view returns (uint) {
return
((balanceOf[_account] *
(rewardPerToken() - userRewardPerTokenPaid[_account])) / 1e18) +
rewards[_account];
}
function getReward() external updateReward(msg.sender) {
uint reward = rewards[msg.sender];
if (reward > 0) {
rewards[msg.sender] = 0;
rewardsToken.transfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}

These functions calculate the rewards earned by a user and allow them to claim their rewards.

Setting Reward Parameters

function setRewardsDuration(uint _duration) external onlyOwner {
require(finishAt < block.timestamp, "reward duration not finished");
duration = _duration;
emit RewardDurationUpdated(_duration);
}
function notifyRewardAmount(uint _amount) external onlyOwner updateReward(address(0)) {
if (block.timestamp >= finishAt) {
rewardRate = _amount / duration;
} else {
uint remainingRewards = (finishAt - block.timestamp) * rewardRate;
rewardRate = (_amount + remainingRewards) / duration;
}

require(rewardRate > 0, “reward rate = 0”);
require(
rewardRate * duration <= rewardsToken.balanceOf(address(this)),
“reward amount > balance”
);

finishAt = block.timestamp + duration;
updatedAt = block.timestamp;
emit RewardNotified(_amount);
}

These functions allow the owner to set the reward duration and notify the contract of the reward amount.

Utility Functions

function _min(uint x, uint y) private pure returns (uint) {
return x <= y ? x : y;
}

Beyond the Basics: The Power of Decentralized Staking

The StakingRewards contract offers several advantages, including:

  • Transparency: All transactions and reward calculations are visible on the blockchain.
  • Security: Smart contract logic ensures funds are handled correctly.
  • Incentives: Encourages long-term participation and loyalty.
  • Automation: Automatically calculates and distributes rewards based on staking activity.

Conclusion: Unlocking the Future of Staking

The StakingRewards smart contract on BTTC is more than just code — it’s a gateway to passive income and decentralized finance. By leveraging blockchain technology, a more transparent, efficient, and accessible staking ecosystem is created.

As users explore the potential of this contract on BTTC, it represents not just staking tokens, but pioneering a new era of decentralized finance and community participation.

Image source: Shutterstock


Source: https://blockchain.news/news/exploring-stakingrewards-contract-bttc