basically what I am trying to do is create a contract that different wallets can send MATIC to one single wallet and after some time withdraw with some reward as MATIC. ie. Stake 100 matic, then withdraw 110 matic with rewards.

Below is my code, I am deploying with 0x0000000000000000000000000000000000001010 test-net matic. I can successfully run but when I'm trying to stake with the value of 1 or 10 I am getting gas estimation error.

What am I doing wrong?

enter image description here

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract StakingContract is Ownable {
    IERC20 public token;
    uint256 public stakingDuration = 30 days;
    uint256 public penaltyPercentage = 50;
    uint256 public interestRate = 15;
    struct User {
        uint256 balance;
        uint256 lastStakeTime;
    mapping(address => User) public users;

     // starting owner address
    address public constant initialOwnerAddress = 0x28362251e41186e518F1F2df2e4cB03F1690b6f0;

    constructor(address _tokenAddress) Ownable(msg.sender) {
        token = IERC20(_tokenAddress);
        transferOwnership(initialOwnerAddress); // starting owner

    function stake(uint256 amount) public {
        require(amount > 0, "Staked amount must be greater than 0");
        require(token.transferFrom(msg.sender, address(this), amount), "Token transfer failed");
        User storage user = users[msg.sender];
        require(user.balance == 0, "User has an active stake");
        user.balance = amount;
        user.lastStakeTime = block.timestamp;

    function withdraw() public {
        User storage user = users[msg.sender];
        require(user.balance > 0, "User has no active stake");
        uint256 stakedTime = block.timestamp - user.lastStakeTime;
        if (stakedTime < stakingDuration) {
            uint256 penaltyAmount = (user.balance * penaltyPercentage) / 100;
            user.balance -= penaltyAmount;
            require(token.transfer(msg.sender, user.balance), "Token transfer failed");
        } else {
            uint256 interest = (user.balance * interestRate * stakedTime) / (100 * stakingDuration * 365 days);
            user.balance += interest;
            require(token.transfer(msg.sender, user.balance), "Token transfer failed");
        user.balance = 0;

    function getContractBalance() public view onlyOwner returns (uint256) {
        return token.balanceOf(address(this));
  • Hi! Could you please explain what you mean when you say that you're deploying with 0x...1010? Commented Nov 2, 2023 at 11:47

1 Answer 1


I see you're using testnet MATIC, which is probably on Mumbai. Mumbai seems to be down at the moment. https://mumbai.polygonscan.com/ shows that the last block/transaction was over 4 hours ago.

  • Yes it is Mumbai, just tried again and got the same error. I can deploy and use the transfer ownership function succesfully with. Only issue is the stake funcion. For some reason its not accepting my input. What can I do to understand the core of the issue?
    – nihilisama
    Commented Nov 1, 2023 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.