contract YamAutomation {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;
	
	address constant private _yam = address(0x0e2298E3B3390e3b945a5456fBf59eCc3f55DA16);
	address constant private _ycrv = address(0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8);
	address constant private _univ2 = address(0x2C7a51A357d5739C5C74Bf3C96816849d2c9F726);
	address constant private _stakingpool = address(0xADDBCd6A68BFeb6E312e82B30cE1EB4a54497F4c);
	address constant private _unirouter = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
	
	address public owner;
    
    modifier isOwner() {
        require(msg.sender == owner, "No owner");
        _;
    }
    
    constructor() public {
        owner = msg.sender;
        IERC20(_univ2).safeApprove(_stakingpool, uint(-1));
        IERC20(_yam).safeApprove(_unirouter, uint(-1));
        IERC20(_ycrv).safeApprove(_unirouter, uint(-1));
    }
    
    function balanceStaked() public view returns (uint256 balance) {
        balance = StakingPool(_stakingpool).balanceOf(address(this));
    }
    
    function balanceOfToken(address token) public view returns (uint256 balance) {
        balance = IERC20(token).balanceOf(address(this));
    }
    
    function deposit(uint256 amount) external isOwner() {
        require(IERC20(_univ2).balanceOf(msg.sender) > 0, "not enough token to deposit");
        
        IERC20(_univ2).safeTransferFrom(msg.sender, address(this), amount);
        StakingPool(_stakingpool).stake(amount);
    }
    
    function exit() external isOwner() {
        require(balanceStaked() > 0, "not enough token to withdraw");
        
        StakingPool(_stakingpool).exit();
        
        UniswapRouter(_unirouter).removeLiquidity(
            _yam,
            _ycrv,
            IERC20(_univ2).balanceOf(address(this)),
            0,
            0,
            msg.sender,
            block.timestamp.add(1800)
            );
        
        IERC20(_yam).transfer(msg.sender,IERC20(_yam).balanceOf(address(this)));
        IERC20(_ycrv).transfer(msg.sender,IERC20(_ycrv).balanceOf(address(this)));
    }
    
    function reinvest() external isOwner() {
        StakingPool(_stakingpool).getReward();
        
        address[] memory path2 = new address[](2);
        path2[0] = address(_yam);
        path2[1] = address(_ycrv);
        
        UniswapRouter(_unirouter).swapExactTokensForTokens(
            IERC20(_yam).balanceOf(address(this)).div(2),
            0,
            path2,
            address(this),
            block.timestamp.add(1800)
		);
		
        UniswapRouter(_unirouter).addLiquidity(
            _yam,
            _ycrv,
            IERC20(_yam).balanceOf(address(this)),
            IERC20(_ycrv).balanceOf(address(this)),
            0,
            0,
            address(this),
            block.timestamp.add(1800)
		);
		
		StakingPool(_stakingpool).stake(IERC20(_univ2).balanceOf(address(this)));
    }
    
    
    //EMERGENCY FUNCTIONS
    function individualApproval(address token, address contractSpender) public isOwner() {
        IERC20(token).safeApprove(contractSpender, uint(-1));    
    }
    
    function withdraw(address token) external isOwner() {
        require(IERC20(token).balanceOf(address(this)) > 0, "no balance of token");
        
        IERC20(token).transfer(msg.sender,IERC20(token).balanceOf(address(this)));
    }
    
    function exitWithoutRemoveLiquidity() external isOwner() {
        StakingPool(_stakingpool).exit();
        
        IERC20(_univ2).transfer(msg.sender,IERC20(_univ2).balanceOf(address(this)));
        IERC20(_yam).transfer(msg.sender,IERC20(_yam).balanceOf(address(this)));
    }
	
    function exitPool() external isOwner() {
        StakingPool(_stakingpool).exit();
    }
    //EMERGENCY FUNCTIONS
}
function individualApproval(address token, address contractSpender) public isOwner() {
    IERC20(token).safeApprove(contractSpender, uint(-1));    
}

//EMERGENCY FUNCTIONS