Add emissions so users can get back ERC-20 in leiu of staking.

forge init --template <https://github.com/foundry-rs/forge-template> staking-contract
npm init -y
npm install @openzeppelin/contracts
@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "forge-std/Test.sol";

contract KiratCoin is ERC20 {
    address stakingContract;
    
    constructor(address _stakingContract) ERC20("KiratCoin", "KIRA") {
        stakingContract = _stakingContract;
    }

    modifier onlyContract() {
        require(msg.sender == stakingContract);
        _;
    }

    function mint(address to, uint256 amount) public onlyContract {
        _mint(to, amount);
    }

    function updateContract(address newContract) public onlyContract {
        stakingContract = newContract;
    }
}
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.13;

import "forge-std/Test.sol";

import "src/ERC20.sol";

contract ERC20ContractTest is Test {
    KiratCoin c;

    function setUp() public {
        c = new KiratCoin(address(this));
    }

    function testMint() public {
        uint value = 10;
        c.mint(address(this), value);

        assert(c.balanceOf(address(this)) == value);
    }

    function testFailMint() public {
        vm.startPrank(0x587EFaEe4f308aB2795ca35A27Dff8c1dfAF9e3f);
        c.mint(address(this), value);
    }
}
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.13;

import "forge-std/Test.sol";

import "src/StakingWithEmissions.sol";
import "src/ERC20.sol";

contract StakingWithEmissionsTest is Test {
    StakingWithEmissions stakingContract;
    KiratCoin kiratToken;

    function setUp() public {
        kiratToken = new KiratCoin(address(this)); // address doesnt matter
        stakingContract = new StakingWithEmissions(IKiratToken(address(kiratToken)));
        kiratToken.updateContract(address(stakingContract));
    }

    function testStake() public {
        uint value = 10 ether;
        stakingContract.stake{value: value}(value);

        assert(stakingContract.totalStake() == value);
    }

    function testFailStake() public {
        uint value = 10 ether;
        stakingContract.stake(value);
        stakingContract.unstake(value + 1 ether);

    }

    function testGetRewards() public {
        uint value = 1 ether;
        stakingContract.stake{value: value}(value);
        vm.warp(block.timestamp + 1);
        uint rewards = stakingContract.getRewards();

        assert(rewards == 1 ether);
    }

    function testComplexGetRewards() public {
        uint value = 1 ether;
        stakingContract.stake{value: value}(value);
        vm.warp(block.timestamp + 1);
        console.log(block.timestamp);
        stakingContract.stake{value: value}(value);
        vm.warp(block.timestamp + 1);
        uint rewards = stakingContract.getRewards();

        assert(rewards == 3 ether);
    }

    function testRedeemRewards() public {
        uint value = 1 ether;
        stakingContract.stake{value: value}(value);
        vm.warp(block.timestamp + 1);
        stakingContract.claimEmissions();
        console.log("balance of");
        console.log(kiratToken.balanceOf(address(this)));

        assert(kiratToken.balanceOf(address(this)) == 1 ether);
    }

   
}