Hello, I'm developing a rewards contract, I set up the entire calculation and division process it pays for (block.timestamp) in the REMIX IDE every time I withdraw the rewards it resets and starts from 0 again, but when it goes for blockchain it does not reset.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
import "./ArcaneCards.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
interface Arcanecards {
function totalSupply() external view returns (uint);
function transfer(address recipient, uint256 amount) external returns (bool) ;
function transferFrom( address sender, address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function decimals() external view returns (uint8);
}
contract Staking is Ownable {
using SafeMath for uint256;
using Math for uint;
ArcaneCards public arcanecards;
/**
* Estes são os Tokens responsaveis pelo Stake
* ArcaneCards é o Token Nativo aonde os usuario Apostam ele
* Recebem StoneCards e depoís trocam novamente por ArcaneCards
* Stone Cards é o Token de governança seu valor para ArcaneCards
* É de 1:1 (um para um) ele não tem valor de mercado
* Sua utilidade é apenas para governança do sistema
*/
constructor (
ArcaneCards _arcanecards
)
{
arcanecards = _arcanecards;
}
uint private _poolBalance;
uint private _staking;
uint256 private _stakingReward;
uint256 public rewardPercent = 800; // 0,07407407% Percent Per Block
uint public rewardsPerHour = 5;
// Mapeamento de Estruturas
mapping(address => uint256) public stakingBalance;
mapping(address => uint) public rewardBalance;
mapping(address => uint256) public startBlock;
mapping(address => bool) public isStaking;
function stake(uint256 _amount) external {
require(_amount > 0);
require(_poolBalance > 0, "saldo igual a zero");
arcanecards.transferFrom(msg.sender, address(this), _amount);
stakingBalance[msg.sender] = SafeMath.add(stakingBalance[msg.sender], _amount);
_staking += _amount;
startBlock[msg.sender] = block.timestamp;
isStaking[msg.sender] = true;
}
function unstake() external {
require(stakingBalance[msg.sender] > 0);
require(recompensaPorUser(msg.sender) == 0, "seu saldo de recompensas deve ser zero");
uint balanceUser = SafeMath.sub(_staking, stakingBalance[msg.sender]);
_staking = balanceUser;
uint balanceStaking = stakingBalance[msg.sender];
stakingBalance[msg.sender] = 0;
arcanecards.approve(address(this), balanceStaking);
arcanecards.transferFrom(address(this), msg.sender, balanceStaking);
isStaking[msg.sender] = false;
}
function unstakeReward() external {
require(_poolBalance > 0, "saldo igual a zero");
require(recompensaPorUser(msg.sender) > 0, "saldo menor doque 0");
uint balanceReward = SafeMath.sub(_poolBalance, recompensaPorUser(msg.sender));
_poolBalance = balanceReward;
uint stakingTime = recompensaPorUser(msg.sender);
if (rewardBalance[msg.sender] != 0) {
uint oldReward = rewardBalance[msg.sender];
rewardBalance[msg.sender] = 0;
stakingTime = SafeMath.add(stakingTime, oldReward);
}
require(rewardBalance[msg.sender] < stakingBalance[msg.sender], "saldo maior doque staking");
startBlock[msg.sender] = block.timestamp;
arcanecards.approve(address(this), stakingTime);
arcanecards.transferFrom(address(this), msg.sender, stakingTime);
}
function mintAddPool(uint256 _amount) public onlyOwner{
require(_amount > 0);
arcanecards.transferFrom(msg.sender, address(this), _amount);
_poolBalance += _amount;
}
function removePoolBalance() public onlyOwner {
_poolBalance = 0;
arcanecards.approve(address(this), _poolBalance);
arcanecards.transferFrom(address(this), msg.sender, _poolBalance);
}
function setRewardPercent(uint256 percent) external onlyOwner {
rewardPercent = percent;
}
function setRewardsPerHour(uint256 percent) external onlyOwner {
rewardsPerHour = percent;
}
function poolBalance() public view returns(uint) {
return _poolBalance;
}
function rewardStaking() public view returns(uint) {
return _stakingReward;
}
function stakeBalance() public view returns(uint) {
return _staking;
}
//---Recompensa de cada Bloco por Usuario---//
function recompensaPorUser(address _usr) public view returns(uint) {
uint256 rewardAmount = (((block.timestamp - startBlock[msg.sender]) / rewardsPerHour) * stakingBalance[_usr]) / rewardPercent;
return rewardAmount;
}
function percentPool() public view returns(uint) {
uint256 rewardAmount = SafeMath.div(SafeMath.mul(SafeMath.div(1, 3600), _poolBalance), rewardPercent);
uint definePercentPool = SafeMath.mul(rewardAmount, 100);
uint percentFinal = SafeMath.mul(SafeMath.mul(definePercentPool, 24), 365);
return percentFinal;
}
}
This is code in solidity
https://testnet.bscscan.com/address/0x5A9beA54a6aBF35Da08eBe04766f0E6E39C08e08#code
I deployed it on testnet, if you go to rewardPoruser, you can see the calculation but as I said above on the blockchain it doesn't change, the problem is that I'm building a Dapp and now I can't put the exact user reward because of this could someone give me some explanation about this?
OBS: The rewards are falling correctly, the calculation does everything right, the only error I'm seeing is visually (and unfortunately that's what I need most now)