contract FRTTreasury is LPTokenWrapper, Ownable {
    IERC20 public REWARD_TOKEN = IERC20(0x561695f9556AF49C2B22F71e55b7b0B6F673834f); // EDIT_ME: Reward token - FRT
    address public gov;
    address public monetaryPolicy;

    uint256 public constant DURATION = 7 days;

    uint256 public origTotalSupply = 0;

    uint256 public initreward = 0;
    uint256 public periodFinish = 0;
    uint256 public rewardRate = 0;
    uint256 public lastUpdateTime;

    event RewardAdded(uint256 reward);
    event RewardPaid(address indexed user, uint256 reward);

    constructor () public {
        origTotalSupply = REWARD_TOKEN.totalSupply();


        initreward = origTotalSupply.mul(10).div(1000);

        notifyRewardAmount(initreward);
    }

    function setGov(address _governance) public onlyOwner {
        gov = _governance;
    }

    function setMonetaryPolicy(address monetaryPolicy_) external onlyOwner
    {
        monetaryPolicy = monetaryPolicy_;
    }

    function lastTimeRewardApplicable() public view returns (uint256) {
        return Math.min(block.timestamp, periodFinish);
    }

    function sendReward(uint256 rate, address account) public checkhalve 
    {
        require(msg.sender == gov || msg.sender == monetaryPolicy, "Not Allowed to Send");
        uint256 reward = initreward.mul(rate).div(1000); //Sets the reward according to a rate that the caller will set.
        uint256 limiter = 100;
        if (reward > 0) {

            // scaled by nowTotalSupply / origTotalSupply when claiming reward
            uint256 nowTotalSupply = REWARD_TOKEN.totalSupply();
            reward = reward.mul(nowTotalSupply).div(origTotalSupply);
            //Limit to 100frt max!!.
            if (reward > limiter.mul(1e18))
            {
                reward = limiter.mul(1e18);
            }
            REWARD_TOKEN.safeTransfer(account, reward);
            
            emit RewardPaid(account, reward);
        }
    }

    modifier checkhalve(){
        if (block.timestamp >= periodFinish) {
            initreward = initreward.mul(75).div(100); // yield reduces to 75% every week

            rewardRate = initreward.div(DURATION);
            periodFinish = block.timestamp.add(DURATION);
            emit RewardAdded(initreward);
        }
        _;
    }

    function notifyRewardAmount(uint256 reward) private
    {
        if (block.timestamp >= periodFinish) {
            rewardRate = reward.div(DURATION);
        } else {
            uint256 remaining = periodFinish.sub(block.timestamp);
            uint256 leftover = remaining.mul(rewardRate);
            rewardRate = reward.add(leftover).div(DURATION);
        }

        lastUpdateTime = block.timestamp;
        periodFinish = block.timestamp.add(DURATION);
        emit RewardAdded(reward);
    }
     //Affects the reward rate.
    function changeInitReward(uint256 reward) public onlyOwner {
        initreward = reward;
        notifyRewardAmount(initreward); //Will evaluate if its worth to do.
    }
    
    //In case community decides to move the Rewards to another contract.
    function recoverRewards(address account) public onlyOwner {
        uint256 reward = REWARD_TOKEN.balanceOf(address(this));
        REWARD_TOKEN.safeTransfer(account, reward);
    }

}
//This is going to be owned by the timelock
function changeInitReward(uint256 reward) public onlyOwner {
    initreward = reward;
    notifyRewardAmount(initreward); //Will evaluate if its worth to do.
}

//Affects the reward rate.