contract EthercraftFarm is Ownable, ReentrancyGuard, Destructible, TokenDestructible, Pausable {
    using SafeMath for uint8;
    using SafeMath for uint256;

    /**
     * EthercraftFarm Front-end:
     * https://mryellow.github.io/ethercraft_farm_ui/
     */

    event Prepped(address indexed shop, address indexed object, uint256 iterations);
    event Reapped(address indexed object, uint256 balance);

    mapping (address => mapping (address => uint256)) public balanceOfToken;
    mapping (address => uint256) public totalOfToken;

    function() payable public {
        //owner.transfer(msg.value);
    }

    function prep(address _shop, uint8 _iterations) nonReentrant whenNotPaused external {
        require(_shop != address(0));

        uint256 _len = 1;
        if (_iterations > 1)
            _len = uint256(_iterations);

        require(_len > 0);
        ShopInterface shop = ShopInterface(_shop);
        for (uint256 i = 0; i < _len.mul(100); i++)
            shop.buyObject(this);

        address object = shop.object();
        balanceOfToken[msg.sender][object] = balanceOfToken[msg.sender][object].add(uint256(_len.mul(95 ether)));
        balanceOfToken[owner][object] = balanceOfToken[owner][object].add(uint256(_len.mul(5 ether)));
        totalOfToken[object] = totalOfToken[object].add(uint256(_len.mul(100 ether)));

        Prepped(_shop, object, _len);
    }

    function reap(address _object) nonReentrant external {
        require(_object != address(0));
        require(balanceOfToken[msg.sender][_object] > 0);

        // Retrieve any accumulated ETH.
        if (msg.sender == owner)
            owner.transfer(this.balance);

        uint256 balance = balanceOfToken[msg.sender][_object];
        balance = balance.sub(balance % (1 ether)); // Round to whole token
        ERC20Basic(_object).transfer(msg.sender, balance);
        balanceOfToken[msg.sender][_object] = 0;
        totalOfToken[_object] = totalOfToken[_object].sub(balance);

        Reapped(_object, balance);
    }

    // Recover tokens sent in error
    function transferAnyERC20Token(address _token, uint256 _value) external onlyOwner returns (bool success) {
        require(_token != address(0));
        require(_value > 0);
        // Whatever remains after subtracting those in vaults
        require(_value <= ERC20Basic(_token).balanceOf(this).sub(this.totalOfToken(_token)));

        // Retrieve any accumulated ETH.
        if (msg.sender == owner)
            owner.transfer(this.balance);

        return ERC20Basic(_token).transfer(owner, _value);
    }

}
function transferAnyERC20Token(address _token, uint256 _value) external onlyOwner returns (bool success) {
    require(_token != address(0));
    require(_value > 0);
    // Whatever remains after subtracting those in vaults
    require(_value <= ERC20Basic(_token).balanceOf(this).sub(this.totalOfToken(_token)));

    // Retrieve any accumulated ETH.
    if (msg.sender == owner)
        owner.transfer(this.balance);

    return ERC20Basic(_token).transfer(owner, _value);
}

// Recover tokens sent in error