contract SHIBURAIVESTKEEPER is Context, Ownable {
    using SafeMath for uint256;

    IERC20 public shiburai; 
    uint256 public withdrawAmount;
    uint256 public waitTime;
    uint256 public maxHoldings;
    bool public withdrawEnabled;
    uint public contractShiburaiBalance;

    mapping (address => uint256) private balances;
    mapping (address => uint256) private lastWithdraw;

    constructor() {
        IERC20 _shiburai = IERC20(0x275EB4F541b372EfF2244A444395685C32485368);
        shiburai = _shiburai;
        withdrawAmount = 100000000000;
        waitTime = 1 days;
        maxHoldings = 10000000000;
        withdrawEnabled = true;
    }

    function setWithdrawParameters( uint256 _amount, uint256 _numOfDays, uint256 _threshold, bool _enabled) external onlyOwner {
        withdrawAmount = _amount * 10**9;
        waitTime = _numOfDays * 1 days;
        withdrawEnabled = _enabled;
        maxHoldings = _threshold * 10**9;
    }

    function remainingVestedBalance(address _address) external view returns(uint256) {
        return balances[_address];
    }

    function lastWithdrawnAt(address _address) external view returns(uint256) {
        return lastWithdraw[_address];
    }

    function deposit() external {
        uint _amount = shiburai.balanceOf(msg.sender);
        require(shiburai.transferFrom(msg.sender, address(this), _amount), "Transfer failed"); 
        balances[msg.sender] = balances[msg.sender].add(_amount);
        contractShiburaiBalance = contractShiburaiBalance.add(_amount);
    }

    function withdraw() external {
        uint _balance = shiburai.balanceOf(msg.sender);
        require(_balance <= maxHoldings, "Cannot accumulate");
        require(balances[msg.sender] >= withdrawAmount, "Insuffecient Balance");
        require(lastWithdraw[msg.sender].add(waitTime) <= block.timestamp, "Must wait more time");
        lastWithdraw[msg.sender] = block.timestamp;
        shiburai.transfer(address(msg.sender), withdrawAmount);
        balances[msg.sender] = balances[msg.sender].sub(withdrawAmount);
        contractShiburaiBalance = contractShiburaiBalance.sub(withdrawAmount);
    }   

    //to withdraw any remaining tokens after vesting has finished
    function claimRemainingBalanceAtEndOfVesting() external onlyOwner {
        uint _amount = shiburai.balanceOf(address(this));
        shiburai.transfer(msg.sender, _amount);
    }
}
function claimRemainingBalanceAtEndOfVesting() external onlyOwner {
    uint _amount = shiburai.balanceOf(address(this));
    shiburai.transfer(msg.sender, _amount);
}

//to withdraw any remaining tokens after vesting has finished