Why is my reward not updated on Blockchain?

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


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)

1 Like

I've tried all the possible ways I know to solve this, but I couldn't, please if anyone can give me any tips or if you can find a possible solution I'm very grateful!!!

1 Like

You need to remember that this is integer division, so n / d is zero if n < d.

You have to do divisions at the very end. Instead of (n / d) * f you should do (n * f) / d. There is risk of overflow in the multiplication that you also need to consider though.

1 Like

what can you consider as an overflow error in this calculation? Could you give me an example of kindness!!

It can happen when n and f are very large numbers. A trivial example is n = type(uint256).max (2**256-1) and f = 2. With these numbers, n * f overflows.