How To Create A Staking Smart Contract

Posted By : Ashish

Apr 21, 2023

In this article, we provide a step-by-step guide to staking smart contract development, deployment, and testing.

 

What are Smart Contracts?

 

A smart contract is a computer program that executes the rules of a contract automatically when certain conditions are satisfied. These contracts are often kept on a blockchain, ensuring their tamper-proof and transparent nature. Smart contracts can be used for a variety of applications, including financial transactions, supply chain management, and enforcing agreements between parties.

 

What is a Staking Smart Contract?

 

A staking smart contract is a type of blockchain-based contract that enables users to lock up their cryptocurrency holdings for a certain period of time, typically in exchange for rewards or benefits. Staking smart contracts facilitate the staking process by automating the process of locking up cryptocurrency holdings and distributing rewards to users who participate in staking.

 

Staking smart contracts are a popular tool for blockchain networks that use a proof-of-stake (PoS) consensus mechanism, as they allow users to participate in the consensus process and earn rewards without having to invest in expensive mining hardware. By staking their cryptocurrency holdings, users can earn rewards while helping to secure the network and maintain its integrity.

 

You may also like | The Increasing Inevitability of Hybrid Smart Contract Development

 

Steps to deploy and test Staking Smart Contract by using Remix

 

Step 1: Define the Token Contract

 

We need to create two ERC20 tokens. One for reward and one for staking.

 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

 

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import "@openzeppelin/contracts/access/Ownable.sol";

 

contract Rtoken is ERC20, Ownable {

   constructor() ERC20("MyToken", "MTK") {}

 

   function mint(address to, uint256 amount) public onlyOwner {

       _mint(to, amount);

   }

}


 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

 

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import "@openzeppelin/contracts/access/Ownable.sol";

 

contract Stoken is ERC20, Ownable {

   constructor() ERC20("MyToken", "MTK") {}

 

   function mint(address to, uint256 amount) public onlyOwner {

       _mint(to, amount);

   }

}

 

Step 2: Define the Staking Contract

 

Now that we have the token contracts in place, we can create the staking contract that will use the token for staking and reward distribution. Here's a basic implementation of the staking contract:

 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

 

 

contract Staking {

   IERC20 public tokenToStake;

   IERC20 public rewardToken;

   mapping(address => uint256) public stakedAmount;

   mapping(address => uint256) public lastStakeTime;

 

   event Staked(address indexed user, uint256 amount);

   event Withdrawn(address indexed user, uint256 amount);

   event RewardPaid(address indexed user, uint256 reward);

 

   constructor(address _tokenToStake, address _rewardToken) {

       tokenToStake = IERC20(_tokenToStake);

       rewardToken = IERC20(_rewardToken);

   }

 

   function stake(uint256 amount) external {

       require(amount > 0, "Staking amount must be greater than 0");

       require(tokenToStake.balanceOf(msg.sender) >= amount, "Insufficient balance");

       require(tokenToStake.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance");

 

       if (stakedAmount[msg.sender] == 0) {

           lastStakeTime[msg.sender] = block.timestamp;

       }

 

       tokenToStake.transferFrom(msg.sender, address(this), amount);

       stakedAmount[msg.sender] += amount;

 

       emit Staked(msg.sender, amount);

   }

 

   function withdraw(uint256 amount) external {

       require(amount > 0, "Withdrawal amount must be greater than 0");

       require(stakedAmount[msg.sender] >= amount, "Insufficient staked amount");

 

       uint256 reward = getReward(msg.sender);

       if (reward > 0) {

           rewardToken.mint(msg.sender, reward);

           emit RewardPaid(msg.sender, reward);

       }

 

       stakedAmount[msg.sender] -= amount;

       tokenToStake.transfer(msg.sender, amount);

 

       emit Withdrawn(msg.sender, amount);

   }

 

   function getReward(address user) public view returns (uint256) {

       uint256 timeElapsed = block.timestamp - lastStakeTime[user];

       uint256 stakedAmountUser = stakedAmount[user];

       if (timeElapsed == 0 || stakedAmountUser == 0) {

           return 0;

       }

 

       uint256 reward = stakedAmountUser * timeElapsed;

 

       return reward;

   }

 

 

   function getStakedBalance(address user) public view returns (uint256) {

       return stakedAmount[user];

   }

}

 

interface IERC20 {

   function totalSupply() external view returns (uint);

 

   function balanceOf(address account) external view returns (uint);

 

   function transfer(address recipient, uint amount) external returns (bool);

 

   function allowance(address owner, address spender) external view returns (uint);

 

   function approve(address spender, uint amount) external returns (bool);

 

   function transferFrom(

       address sender,

       address recipient,

       uint amount

   ) external returns (bool);

 

   function mint(address to, uint256 amount) external;

   event Transfer(address indexed from, address indexed to, uint value);

   event Approval(address indexed owner, address indexed spender, uint value);

}

 

Also, Check | Exploring the Potential of Solana Smart Contract Development


 

Step 3: Deploy the Rtoken, Stoken, and Staking Contract created above on Remix.

 

Step 4: Transfer the Ownership of the reward token to the staking contract

 

Step 5: Let's Test the Staking Smart Contract

 

Mint some tokens for yourself and approve the staking contract with the number of stokens you want to stake.

 


 

Go to the staking contract and use the stake function.

 

Now. click on withdraw after some time.

 

 

You will be able to check your reward token balance.

 

 

Suggested Read | Ethereum Smart Contract Development | Discovering the Potential


Conclusion

 

You may also connect with our skilled smart contract developers if you want to integrate staking smart contract solutions into your projects or have any questions in mind.  
 

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

April 30, 2024 at 06:02 pm

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text