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?
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));
}
}