Address io1asxdtswkr9p6r9du57ecrhrql865tf2qxue6hw

Contract Overview

Balance:
0 IOTX

IOTX Value:
$ 0

Token:
Txn Hash
Block
From
To
Value [Txn Fee]
6985df94820ad50ee2397a930636ed09fe42714ae979b40582e4471d29f0676c 29554661 2024-04-19 05:16:05 +0000 UTC 3 hours ago io1x34u7n5q9qugkvvnkar4uja259uft5gphazsgh  IN    Contract: Aliana 0 IOTX 0.30218
04dea52c8b2981050e2cfddc1e84282b434e5044456eb44ac9695bd7dbfa8647 29554635 2024-04-19 05:13:55 +0000 UTC 3 hours ago io1snegn9z633whz2xvrz8t028z5yzlm9rycjzh55  IN    Contract: Aliana 0 IOTX 0.283256
1cb173da548159cdedde181a9544f89e6698e81919265f491a17da5ca2cf96fa 29554520 2024-04-19 05:04:20 +0000 UTC 3 hours ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.557112
f6ae8f908f6efb67f0bf74312a5c337d1e227fbaa833719ec2b069a5811ec65b 29554301 2024-04-19 04:46:05 +0000 UTC 4 hours ago io1aacd7a42wkzathvh9fca64f9x7qk7u0hy9clvv  IN    Contract: Aliana 0 IOTX 0.404032
1540efb13260d6a5bfa4d651d8c289b7014a2090cba75d6ef362cb9fd3816e70 29554277 2024-04-19 04:44:05 +0000 UTC 4 hours ago io1yggm0zqnzp9j850m5jjhkzhmw7l50r2qdnjhcg  IN    Contract: Aliana 0 IOTX 0.496360
e5882802b6534901074e234f7aed548d81cdadde9a77903a740a0cef0868f1da 29553998 2024-04-19 04:20:50 +0000 UTC 4 hours ago io1umf53x3vn3mpnaeuc67qz0844jyz0cfnznlll7  IN    Contract: Aliana 0 IOTX 0.294673
8a1ecaf66acebf84d95cef3ecb8dc029fd86455310cad39a0a24c8901f1f0f47 29553967 2024-04-19 04:18:15 +0000 UTC 4 hours ago io1weh7uvjdezq5pkudup98m3rmgqj8k4rdad0nzl  IN    Contract: Aliana 0 IOTX 0.313556
46aaccf10e3e52eac2ff8e9e94d8a95680f671debc81d0d15fc19f0e12813380 29553846 2024-04-19 04:08:10 +0000 UTC 4 hours ago io10wc2t8akxxkn0se58282gt4j3gl7ngfv2954jj  IN    Contract: Aliana 0 IOTX 0.313556
f9a0a4373447f16d470cc8031f20b7aa353cd29b2593540d077f0dad06e428fa 29553768 2024-04-19 04:01:40 +0000 UTC 4 hours ago io1d603npxhrxuqt6ljp5cncs8wt7yztnxqchg7tz  IN    Contract: Aliana 0 IOTX 0.582940
9382a485aa20fab97872a9c2f03a4b220d6f541e95d31740d76d324bf556b06a 29553767 2024-04-19 04:01:35 +0000 UTC 4 hours ago io1d603npxhrxuqt6ljp5cncs8wt7yztnxqchg7tz  IN    Contract: Aliana 0 IOTX 0.605759
8a9302325f779ed5e95fcaede56fba0e3065c84f48b4ff0a5d3859883594a35d 29549424 2024-04-18 21:59:40 +0000 UTC 10 hours ago io1ym4ku2mnzjuxcc9mw0ujzvspyrkvgk8ph98dsx  IN    Contract: Aliana 0 IOTX 0.572112
f5c6b5098711363132650c8162bb73343a6cd0e9f1fc018694be7aafa130200d 29547137 2024-04-18 18:49:05 +0000 UTC 14 hours ago io18agx0hj666va9v9hyasrkz4xa836v57dyrtxkl  IN    Contract: Aliana 0 IOTX 0.572112
b2bb608258376c558decee272ce3b9e1e67ebaa8a832e24b23e2c7db08a587ff 29547123 2024-04-18 18:47:55 +0000 UTC 14 hours ago io18agx0hj666va9v9hyasrkz4xa836v57dyrtxkl  IN    Contract: Aliana 0 IOTX 0.572112
131d93de23483490c4e2da2d00ae2c87c5c51509d1ca4c0078ace5fcf83e1274 29546833 2024-04-18 18:23:45 +0000 UTC 14 hours ago io1v9z2hfwhzg7u4eh9nfdjkcahf5j4qaaavgrd20  IN    Contract: Aliana 0 IOTX 0.604292
c14ecf46ddec3fe07e0a384a7685e5c549a5cd33248572d4da9a720729722c9e 29544945 2024-04-18 15:46:15 +0000 UTC 17 hours ago io1np8487c5gs9ckyljw4t64qfsaggevma868q2cx  IN    Contract: Aliana 0 IOTX 0.283256
6db3f720341d020d4d212f8fe3c38cdd5e9ab229e7f97a16c8c399d26b1143bf 29544118 2024-04-18 14:37:20 +0000 UTC 18 hours ago io1t026pc3r63lh42qn85fulwsp8jw7x5fn928r65  IN    Contract: Aliana 0 IOTX 0.566512
1e669646fc28deed68a11612642c9c7a3aecddd6398cf7352b573dd48c52238d 29543288 2024-04-18 13:28:10 +0000 UTC 19 hours ago io1xay7um85lcqj2x3hc2e7ecqdpunew0jd9q6ze8  IN    Contract: Aliana 0 IOTX 0.081909
36c17c3d6ec12b0b2ae16c8aef2a331aa860f34a5dfbc0c251420829b54fd16d 29542107 2024-04-18 11:49:45 +0000 UTC 21 hours ago io1mqh0qudvq6p4dht0r83shnfxdk9f9x2c7selyt  IN    Contract: Aliana 0 IOTX 0.557112
45ca2a5c6f25402aac4ac5568fc0f382d1de84238f767e0d558b61bd12fbf23e 29541921 2024-04-18 11:34:15 +0000 UTC 21 hours ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.557112
10529b6392d1b94b79f3ae60429bd3739b0304b3c343dc138bf5b9e73b5c5430 29539391 2024-04-18 08:03:25 +0000 UTC one day ago io1fu6l3z7c4xyzsm4u640g3n58xsasn0h895cams  IN    Contract: Aliana 0 IOTX 0.610646
6363d608440bf7fb2b109c4f6e2454a0bfa5e6d4277fc586c30a8ddc4610b73a 29538895 2024-04-18 07:22:05 +0000 UTC one day ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.557112
9b2f2380ad4df15f3e9b097d95b4dfb17fe84aab55e27ab7ee98a8c3a488af74 29532664 2024-04-17 22:42:50 +0000 UTC one day ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.632712
858ae48e8d425cc62531738e914d78c7f68ac36a626fc362952530b50eeb2951 29532661 2024-04-17 22:42:35 +0000 UTC one day ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.557112
047a6df765cb8368b968c322cdd643b3cb72f8cbd4eb6ee38d7d5255e0679dc9 29532576 2024-04-17 22:35:30 +0000 UTC one day ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.632712
b509bda74a5bccd0acbb72b4b11732bd940ea8c95c4c95165e4536e9c3611e91 29532042 2024-04-17 21:51:00 +0000 UTC one day ago io1rhnwa7hnay8hmvzdwm8ua8s32rygv6cr7lskgn  IN    Contract: Aliana 0 IOTX 0.678666
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Aliana

Compiler Version
v0.5.5+commit.47a71e8f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
File 1 of 23: @openzeppelin/contracts/introspection/IERC165.sol
pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 2 of 23: @openzeppelin/contracts/token/ERC20/IERC20.sol
pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 3 of 23: @openzeppelin/contracts/token/ERC20/SafeERC20.sol
pragma solidity ^0.5.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 4 of 23: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol
pragma solidity ^0.5.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 5 of 23: ./contract/aliana/AlianaBase.sol
pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "./IGeneScience.sol";
import "./GFAccessControl.sol";
import "./ISaleClockAuction.sol";

/// @title Base contract for GameAlianas. Holds all common structs, events and base variables.
/// @dev See the AlianaCore contract documentation to understand how the various contract facets are arranged.
contract AlianaBase is GFAccessControl, ERC721Full {
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public whenNotPaused {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public whenNotPaused {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public whenNotPaused {
        super.safeTransferFrom(from, to, tokenId, _data);
    }

    /// @dev The address of the sibling contract that is used to implement the sooper-sekret
    ///  genetic combination algorithm.
    IGeneScience internal geneScience;

    /// @dev Update the address of the genetic contract, can only be called by the CEO.
    /// @param _address An address of a GeneScience contract instance to be used from this point forward.
    function setGeneScienceAddress(IGeneScience _address) public onlyCEO {
        require(_address.isGeneScience(), "Aliana: not gene");

        // Set the new contract address
        geneScience = _address;
    }

    function getGeneScienceAddress()
        external
        view
        onlyCLevelOrWhitelisted
        returns (address)
    {
        return address(geneScience);
    }

    function isAliana() external pure returns (bool) {
        return true;
    }

    // Initializing an ERC-721 Token named 'Vipers' with a symbol 'VPR'
    constructor() public ERC721Full("Game Fantasy Alianas", "GFA") {}

    /*** DATA TYPES ***/

    /// @dev The main Aliana struct. Every cat in GameAlianas is represented by a copy
    ///  of this structure, so great care was taken to ensure that it fits neatly into
    ///  exactly two 256-bit words. Note that the order of the members in this structure
    ///  is important because of the byte-packing rules used by Ethereum.
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Aliana {
        // The Aliana's genetic code is packed into these 256-bits, the format is
        // sooper-sekret! A cat's genes never change.
        uint256 genes;
        // The timestamp from the block when this cat came into existence.
        uint64 birthTime;
        // The ID of the parents of this aliana, set to 0 for gen0 cats.
        // Note that using 32-bit unsigned integers limits us to a "mere"
        // 4 billion cats. This number might seem small until you realize
        // that Ethereum currently has a limit of about 500 million
        // transactions per year! So, this definitely won't be a problem
        // for several years (even as Ethereum learns to scale).
        uint64 matronId;
        uint64 sireId;
    }

    /*** STORAGE ***/

    /// @dev An array containing the Aliana struct for all Kitties in existence. The ID
    ///  of each cat is actually an index into this array.
    Aliana[] public alianas;

    /// @dev An internal method that creates a new aliana and stores it. This
    ///  method doesn't do any checking and should only be called when the
    ///  input data is known to be valid. Will generate both a Birth event
    ///  and a Transfer event.
    /// @param _matronId The aliana ID of the matron of this cat (zero for gen0)
    /// @param _sireId The aliana ID of the sire of this cat (zero for gen0)
    /// @param _genes The aliana's genetic code.
    /// @param _owner The inital owner of this cat, must be non-zero (except for the unAliana, ID 0)
    function _createAliana(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _genes,
        address _owner
    ) internal returns (uint256) {
        require(
            geneScience.isValid(int256(alianas.length), _genes),
            "Aliana: genes isn't valid"
        );
        Aliana memory _aliana = Aliana({
            genes: _genes,
            birthTime: uint64(now),
            matronId: uint64(_matronId),
            sireId: uint64(_sireId)
        });
        uint256 newKittenId = alianas.push(_aliana) - 1;

        // This will assign ownership, and also emit the Transfer event as
        // per ERC721 draft
        super._mint(_owner, newKittenId);
        return newKittenId;
    }

    /// @notice Returns all the relevant information about a specific aliana.
    /// @param _id The ID of the aliana of interest.
    function getAliana(uint256 _id)
        external
        view
        returns (
            uint256 birthTime,
            uint256 matronId,
            uint256 sireId,
            uint256 genes,
            uint256 lpLabor
        )
    {
        Aliana storage kit = alianas[_id];

        birthTime = uint256(kit.birthTime);
        matronId = uint256(kit.matronId);
        sireId = uint256(kit.sireId);
        genes = kit.genes;
        lpLabor = uint64(geneScience.geneLpLabor(int256(_id), kit.genes));
    }
}

File 6 of 23: ./contract/aliana/IGeneScience.sol
pragma solidity ^0.5.0;

/// @title SEKRETOOOO
contract IGeneScience {
    /// @dev simply a boolean to indicate this is the contract we expect to be
    function isGeneScience() public pure returns (bool);

    /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor
    /// @param _genes1 genes of mom
    /// @param _genes2 genes of sire
    /// @param _targetBlock target block
    /// @return the genes that are supposed to be passed down the child
    function mixGenes(
        int256 _id1,
        int256 _id2,
        uint256 _genes1,
        uint256 _genes2,
        uint256 _targetBlock
    ) public returns (uint256);

    function geneLpLabor(int256 _id, uint256 _genes)
        public
        pure
        returns (uint256);

    function isValid(int256 _id, uint256 _genes) public pure returns (bool);

    function totalQuality(int256 _id, uint256 _genes)
        public
        pure
        returns (uint256);

    function getAuctionGene(uint256 _id) public pure returns (uint256);
}

File 7 of 23: ./contract/aliana/ISaleClockAuction.sol
pragma solidity ^0.5.0;

/// @title SEKRETOOOO
contract ISaleClockAuction {
    /// @dev simply a boolean to indicate this is the contract we expect to be
    function isAuction() public pure returns (bool);

    function createAuction(
        uint256 _tokenId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration,
        address _seller
    ) external;

    function claimTokens(address token_) public;
}

File 8 of 23: @openzeppelin/contracts/GSN/Context.sol
pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 9 of 23: @openzeppelin/contracts/drafts/Counters.sol
pragma solidity ^0.5.0;

import "../math/SafeMath.sol";

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

File 10 of 23: @openzeppelin/contracts/token/ERC721/ERC721.sol
pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../../drafts/Counters.sol";
import "../../introspection/ERC165.sol";

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping (uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][to] = approved;
        emit ApprovalForAll(_msgSender(), to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the _msgSender() to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransferFrom(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
        _transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _safeMint(address to, uint256 tokenId) internal {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This is an internal detail of the `ERC721` contract and its use is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = to.call(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ));
        if (!success) {
            if (returndata.length > 0) {
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert("ERC721: transfer to non ERC721Receiver implementer");
            }
        } else {
            bytes4 retval = abi.decode(returndata, (bytes4));
            return (retval == _ERC721_RECEIVED);
        }
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

File 11 of 23: @openzeppelin/contracts/token/ERC721/ERC721Full.sol
pragma solidity ^0.5.0;

import "./ERC721.sol";
import "./ERC721Enumerable.sol";
import "./ERC721Metadata.sol";

/**
 * @title Full ERC721 Token
 * @dev This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology.
 *
 * See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
    constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks
    }
}

File 12 of 23: @openzeppelin/contracts/token/ERC721/ERC721Metadata.sol
pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";

contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Base URI
    string private _baseURI;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the URI for a given token ID. May return an empty string.
     *
     * If the token's URI is non-empty and a base URI was set (via
     * {_setBaseURI}), it will be added to the token ID's URI as a prefix.
     *
     * Reverts if the token ID does not exist.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];

        // Even if there is a base URI, it is only appended to non-empty token-specific URIs
        if (bytes(_tokenURI).length == 0) {
            return "";
        } else {
            // abi.encodePacked is being used to concatenate strings
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     *
     * Reverts if the token ID does not exist.
     *
     * TIP: if all token IDs share a prefix (e.g. if your URIs look like
     * `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
     * it and save gas.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI}.
     *
     * _Available since v2.5.0._
     */
    function _setBaseURI(string memory baseURI) internal {
        _baseURI = baseURI;
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a preffix in {tokenURI} to each token's URI, when
    * they are non-empty.
    *
    * _Available since v2.5.0._
    */
    function baseURI() external view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

File 13 of 23: ./contract/aliana/AlianaOwnership.sol
pragma solidity ^0.5.0;

import "./AlianaBase.sol";
import "../token/IApproveAndCallFallBack.sol";

/// @title The facet of the GameAlianas core contract that manages ownership, ERC-721 (draft) compliant.
/// @dev Ref: https://github.com/ethereum/EIPs/issues/721
///  See the AlianaCore contract documentation to understand how the various contract facets are arranged.
contract AlianaOwnership is AlianaBase {
    /// @notice Returns the total number of Kitties currently in existence.
    function totalAlianaSupply() public view returns (uint256) {
        return alianas.length;
    }

    /// @notice Returns a list of all Aliana IDs assigned to an address.
    /// @param _owner The owner whose Kitties we are interested in.
    /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly
    ///  expensive (it walks the entire Aliana array looking for cats belonging to owner),
    ///  but it also returns a dynamic array, which is only supported for web3 calls, and
    ///  not contract-to-contract calls.
    function tokensOfOwner(address _owner)
        external
        view
        returns (uint256[] memory ownerTokens)
    {
        return super._tokensOfOwner(_owner);
    }

    /// @notice `msg.sender` approves `spender_` to send `tokenId_` tokens on
    ///  its behalf, and then a function is triggered in the contract that is
    ///  being approved, `spender_`. This allows users to use their tokens to
    ///  interact with contracts in one function call instead of two
    /// @param spender_ The address of the contract able to transfer the tokens
    /// @param tokenId_ The id of tokens to be approved for transfer
    /// @return True if the function call was successful
    function approveAndCall(
        address spender_,
        uint256 tokenId_,
        bytes memory extraData_
    ) public returns (bool success) {
        approve(spender_, tokenId_);
        IApproveAndCallFallBack(spender_).receiveApproval(
            msg.sender,
            tokenId_,
            address(this),
            extraData_
        );
        return true;
    }

    function setApprovalForAllAndCall(
        address spender_,
        bool approved_,
        bytes memory extraData_
    ) public returns (bool success) {
        setApprovalForAll(spender_, approved_);
        IApproveAndCallFallBack(spender_).receiveApproval(
            msg.sender,
            uint256(-1),
            address(this),
            extraData_
        );
        return true;
    }
}

File 14 of 23: @openzeppelin/contracts/utils/Address.sol
pragma solidity ^0.5.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

File 15 of 23: ./contract/aliana/GFAccessControl.sol
pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

/// @title A facet of AlianaCore that manages special access privileges.
/// @dev See the AlianaCore contract documentation to understand how the various contract facets are arranged.
contract GFAccessControl {
    mapping(address => bool) public whitelist;

    event WhitelistedAddressAdded(address addr);
    event WhitelistedAddressRemoved(address addr);

    /**
     * @dev Throws if called by any account that's not whitelisted.
     */
    modifier onlyWhitelisted() {
        require(whitelist[msg.sender], "not whitelisted");
        _;
    }

    /**
     * @dev add an address to the whitelist
     * @param addr address
     * @return true if the address was added to the whitelist, false if the address was already in the whitelist
     */
    function addAddressToWhitelist(address addr)
        external
        onlyCEO
        returns (bool success)
    {
        return _addAddressToWhitelist(addr);
    }

    /**
     * @dev add an address to the whitelist
     * @param addr address
     * @return true if the address was added to the whitelist, false if the address was already in the whitelist
     */
    function _addAddressToWhitelist(address addr)
        private
        onlyCEO
        returns (bool success)
    {
        if (!whitelist[addr]) {
            whitelist[addr] = true;
            emit WhitelistedAddressAdded(addr);
            success = true;
        }
    }

    /**
     * @dev add addresses to the whitelist
     * @param addrs addresses
     * @return true if at least one address was added to the whitelist,
     * false if all addresses were already in the whitelist
     */
    function addAddressesToWhitelist(address[] calldata addrs)
        external
        onlyCEO
        returns (bool success)
    {
        for (uint256 i = 0; i < addrs.length; i++) {
            if (_addAddressToWhitelist(addrs[i])) {
                success = true;
            }
        }
    }

    /**
     * @dev remove an address from the whitelist
     * @param addr address
     * @return true if the address was removed from the whitelist,
     * false if the address wasn't in the whitelist in the first place
     */
    function removeAddressFromWhitelist(address addr)
        external
        onlyCEO
        returns (bool success)
    {
        return _removeAddressFromWhitelist(addr);
    }

    /**
     * @dev remove an address from the whitelist
     * @param addr address
     * @return true if the address was removed from the whitelist,
     * false if the address wasn't in the whitelist in the first place
     */
    function _removeAddressFromWhitelist(address addr)
        private
        onlyCEO
        returns (bool success)
    {
        if (whitelist[addr]) {
            whitelist[addr] = false;
            emit WhitelistedAddressRemoved(addr);
            success = true;
        }
    }

    /**
     * @dev remove addresses from the whitelist
     * @param addrs addresses
     * @return true if at least one address was removed from the whitelist,
     * false if all addresses weren't in the whitelist in the first place
     */
    function removeAddressesFromWhitelist(address[] calldata addrs)
        external
        onlyCEO
        returns (bool success)
    {
        for (uint256 i = 0; i < addrs.length; i++) {
            if (_removeAddressFromWhitelist(addrs[i])) {
                success = true;
            }
        }
    }

    // This facet controls access control for GameAlianas. There are four roles managed here:
    //
    //     - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart
    //         contracts. It is also the only role that can unpause the smart contract. It is initially
    //         set to the address that created the smart contract in the AlianaCore constructor.
    //
    //     - The CFO: The CFO can withdraw funds from AlianaCore and its auction contracts.
    //
    //     - The COO: The COO can release gen0 alianas to auction, and mint promo cats.
    //
    // It should be noted that these roles are distinct without overlap in their access abilities, the
    // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any
    // address to any role, the CEO address itself doesn't have the ability to act in those roles. This
    // restriction is intentional so that we aren't tempted to use the CEO address frequently out of
    // convenience. The less we use an address, the less likely it is that we somehow compromise the
    // account.

    /// @dev Emited when contract is upgraded - See README.md for updgrade plan
    event ContractUpgrade(address newContract);

    // The addresses of the accounts (or contracts) that can execute actions within each roles.
    address public ceoAddress;
    address public candidateCEOAddress;

    address public cfoAddress;
    address public cooAddress;

    event SetCandidateCEO(address addr);
    event AcceptCEO(address addr);
    event SetCFO(address addr);
    event SetCOO(address addr);

    event Pause(address operator);
    event Unpause(address operator);

    // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked
    bool public paused = false;

    /**
     * @dev The Ownable constructor sets the original `ceoAddress` of the contract to the sender
     * account.
     */
    constructor() public {
        ceoAddress = msg.sender;
        emit AcceptCEO(ceoAddress);
    }

    /// @dev Access modifier for CEO-only functionality
    modifier onlyCEO() {
        require(msg.sender == ceoAddress, "not ceo");
        _;
    }

    /// @dev Access modifier for CFO-only functionality
    modifier onlyCFO() {
        require(msg.sender == cfoAddress, "not cfo");
        _;
    }

    /// @dev Access modifier for COO-only functionality
    modifier onlyCOO() {
        require(msg.sender == cooAddress, "not coo");
        _;
    }

    modifier onlyCLevel() {
        require(
            msg.sender == cooAddress ||
                msg.sender == ceoAddress ||
                msg.sender == cfoAddress,
            "not c level"
        );
        _;
    }

    modifier onlyCLevelOrWhitelisted() {
        require(
            msg.sender == cooAddress ||
                msg.sender == ceoAddress ||
                msg.sender == cfoAddress ||
                whitelist[msg.sender],
            "not c level or whitelisted"
        );
        _;
    }

    /// @dev Assigns a new address to act as the CEO. Only available to the current CEO.
    /// @param _candidateCEO The address of the new CEO
    function setCandidateCEO(address _candidateCEO) external onlyCEO {
        require(_candidateCEO != address(0), "addr can't be 0");

        candidateCEOAddress = _candidateCEO;
        emit SetCandidateCEO(candidateCEOAddress);
    }

    /// @dev Accept CEO invite.
    function acceptCEO() external {
        require(msg.sender == candidateCEOAddress, "you are not the candidate");

        ceoAddress = candidateCEOAddress;
        emit AcceptCEO(ceoAddress);
    }

    /// @dev Assigns a new address to act as the CFO. Only available to the current CEO.
    /// @param _newCFO The address of the new CFO
    function setCFO(address _newCFO) external onlyCEO {
        require(_newCFO != address(0), "addr can't be 0");

        cfoAddress = _newCFO;
        emit SetCFO(cfoAddress);
    }

    /// @dev Assigns a new address to act as the COO. Only available to the current CEO.
    /// @param _newCOO The address of the new COO
    function setCOO(address _newCOO) external onlyCEO {
        require(_newCOO != address(0), "addr can't be 0");

        cooAddress = _newCOO;
        emit SetCOO(cooAddress);
    }

    /*** Pausable functionality adapted from OpenZeppelin ***/

    /// @dev Modifier to allow actions only when the contract IS NOT paused
    modifier whenNotPaused() {
        require(!paused, "paused");
        _;
    }

    /// @dev Modifier to allow actions only when the contract IS paused
    modifier whenPaused() {
        require(paused, "not paused");
        _;
    }

    /// @dev Called by any "C-level" role to pause the contract. Used only when
    ///  a bug or exploit is detected and we need to limit damage.
    function pause() external onlyCEO whenNotPaused {
        paused = true;
        emit Pause(msg.sender);
    }

    /// @dev Unpauses the smart contract. Can only be called by the CEO, since
    ///  one reason we may pause the contract is when CFO or COO accounts are
    ///  compromised.
    /// @notice This is public rather than external so it can be called by
    ///  derived contracts.
    function unpause() public onlyCEO whenPaused {
        // can't unpause if contract was upgraded
        paused = false;
        emit Unpause(msg.sender);
    }

    // Set in case the core contract is broken and an upgrade is required
    address public newContractAddress;

    /// @dev Used to mark the smart contract as upgraded, in case there is a serious
    ///  breaking bug. This method does nothing but keep track of the new contract and
    ///  emit a message indicating that the new address is set. It's up to clients of this
    ///  contract to update to the new contract address in that case. (This contract will
    ///  be paused indefinitely if such an upgrade takes place.)
    /// @param _v2Address new address
    function setNewAddress(address _v2Address) external onlyCEO whenPaused {
        // See README.md for updgrade plan
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    //////////
    // Safety Methods
    //////////

    /// @notice This method can be used by the owner to extract mistakenly
    ///  sent tokens to this contract.
    /// @param token_ The address of the token contract that you want to recover
    ///  set to 0 in case you want to extract ether.
    function claimTokens(address token_) external onlyCEO {
        if (token_ == address(0)) {
            address(msg.sender).transfer(address(this).balance);
            return;
        }

        IERC20 token = IERC20(token_);
        uint256 balance = token.balanceOf(address(this));
        token.transfer(address(msg.sender), balance);

        emit ClaimedTokens(token_, address(msg.sender), balance);
    }

    function withdrawTokens(
        IERC20 token_,
        address to_,
        uint256 amount_
    ) external onlyCEO {
        assert(token_.transfer(to_, amount_));
        emit WithdrawTokens(address(token_), address(msg.sender), to_, amount_);
    }

    ////////////////
    // Events
    ////////////////

    event ClaimedTokens(
        address indexed token_,
        address indexed controller_,
        uint256 amount_
    );

    event WithdrawTokens(
        address indexed token_,
        address indexed controller_,
        address indexed to_,
        uint256 amount_
    );
}

File 16 of 23: ./contract/token/IApproveAndCallFallBack.sol
pragma solidity ^0.5.0;

contract IApproveAndCallFallBack {
    function receiveApproval(
        address from,
        uint256 amount_,
        address token_,
        bytes memory data_
    ) public;
}

File 17 of 23: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol
pragma solidity ^0.5.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Enumerable is IERC721 {
    function totalSupply() public view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) public view returns (uint256);
}

File 18 of 23: ./contract/Aliana.sol
pragma solidity ^0.5.0;

import "./aliana/AlianaOwnership.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./aliana/IGeneScience.sol";

/// @title A facet of AlianaCore that manages Aliana siring, gestation, and birth.
/// @dev See the AlianaCore contract documentation to understand how the various contract facets are arranged.
contract Aliana is AlianaOwnership {
    constructor(IGeneScience _geneAddr) public {
        require(_geneAddr.isGeneScience(), "Aliana: isGeneScience false");
        setGeneScienceAddress(_geneAddr);
        require(
            _createAliana(0, 0, 0, address(this)) == 0,
            "Aliana: card #0 must be my own"
        );
    }

    /// @notice Have a pregnant Aliana give birth!
    /// @param _matronId A Aliana ready to give birth.
    /// @return The Aliana ID of the new kitten.
    /// @dev Looks at a given Aliana and, if pregnant and if the gestation period has passed,
    ///  combines the genes of the two parents to create a new kitten. The new Aliana is assigned
    ///  to the current owner of the matron. Upon successful completion, both the matron and the
    ///  new kitten will be ready to breed again. Note that anyone can call this function (if they
    ///  are willing to pay the gas!), but the new kitten always goes to the mother's owner.
    function mix(uint256 _matronId, uint256 _sireId)
        external
        whenNotPaused
        returns (uint256)
    {
        require(
            _matronId != _sireId,
            "Aliana: only different aliana can be merged"
        );
        require(ownerOf(_matronId) == msg.sender, "Aliana: must be the owner");
        require(ownerOf(_sireId) == msg.sender, "Aliana: must be the owner");

        // Grab a reference to the matron in storage.
        Aliana storage matron = alianas[_matronId];

        Aliana storage sire = alianas[_sireId];

        // Check that the matron is a valid cat.
        require(matron.birthTime != 0, "Aliana: matron birthTime not valid");

        // Check that the matron is a valid cat.
        require(sire.birthTime != 0, "Aliana: sire birthTime not valid");

        uint256 totalCats = totalAlianaSupply();
        // Call the sooper-sekret gene mixing operation.
        uint256 childGenes = geneScience.mixGenes(
            int256(_matronId),
            int256(_sireId),
            matron.genes,
            sire.genes,
            totalCats
        );

        _burn(msg.sender, _matronId);
        _burn(msg.sender, _sireId);

        // Make the new kitten!
        uint256 kittenId = _createAliana(
            _matronId,
            _sireId,
            childGenes,
            msg.sender
        );

        emit Mix(msg.sender, _matronId, _sireId, kittenId);

        // return the new kitten's ID
        return kittenId;
    }

    function burn(uint256 _tokenID) external {
        require(ownerOf(_tokenID) == msg.sender, "Aliana: must be the owner");
        _burn(msg.sender, _tokenID);
    }

    function geneLpLabor(int256 _id, uint256 _gene)
        public
        view
        returns (uint256)
    {
        return geneScience.geneLpLabor(_id, _gene);
    }

    function geneLpLabors(int256[] calldata _ids, uint256[] calldata _genes)
        external
        view
        returns (uint256[] memory)
    {
        uint256[] memory res = new uint256[](_genes.length);
        for (uint256 i = 0; i < _genes.length; i++) {
            res[i] = geneScience.geneLpLabor(_ids[i], _genes[i]);
        }
        return res;
    }

    /// @dev we can create Official alianas, up to a limit. Only callable by Official contract
    /// @param _genes the encoded genes of the kitten to be created, any value is accepted
    /// @param _owner the future owner of the created alianas. Default to contract COO
    function createOfficialAliana(uint256 _genes, address _owner)
        external
        onlyWhitelisted
        returns (uint256)
    {
        return _createAliana(0, 0, _genes, _owner);
    }

    /// @dev we can create Official alianas, up to a limit. Only callable by Official contract
    /// @param _genes the encoded genes of the kitten to be created, any value is accepted
    /// @param _owner the future owner of the created alianas. Default to contract COO
    function createOfficialAliana(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _genes,
        address _owner
    ) external onlyWhitelisted returns (uint256) {
        return _createAliana(_matronId, _sireId, _genes, _owner);
    }

    /// @dev we can create promo alianas, up to a limit. Only callable by COO
    /// @param _genes the encoded genes of the kitten to be created, any value is accepted
    /// @param _owner the future owner of the created alianas. Default to contract COO
    function createPromoAliana(uint256 _genes, address _owner)
        external
        onlyCLevel
        returns (uint256)
    {
        address alianaOwner = _owner;
        if (alianaOwner == address(0)) {
            alianaOwner = msg.sender;
        }

        return _createAliana(0, 0, _genes, alianaOwner);
    }

    event Mix(
        address indexed src,
        uint256 indexed matronId,
        uint256 indexed sireId,
        uint256 kittenId
    );
}

File 19 of 23: @openzeppelin/contracts/math/SafeMath.sol
pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 20 of 23: @openzeppelin/contracts/token/ERC721/ERC721Enumerable.sol
pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./IERC721Enumerable.sol";
import "./ERC721.sol";
import "../../introspection/ERC165.sol";

/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => uint256[]) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Constructor function.
     */
    constructor () public {
        // register the supported interface to conform to ERC721Enumerable via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev Gets the token ID at a given index of the tokens list of the requested owner.
     * @param owner address owning the tokens list to be accessed
     * @param index uint256 representing the index to be accessed of the requested tokens list
     * @return uint256 token ID at the given index of the tokens list owned by the requested address
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev Gets the total amount of tokens stored by the contract.
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev Gets the token ID at a given index of all the tokens in this contract
     * Reverts if the index is greater or equal to the total number of tokens.
     * @param index uint256 representing the index to be accessed of the tokens list
     * @return uint256 token ID at the given index of the tokens list
     */
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);

        _removeTokenFromOwnerEnumeration(from, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to address the beneficiary that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        super._mint(to, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);

        _addTokenToAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {ERC721-_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        _removeTokenFromOwnerEnumeration(owner, tokenId);
        // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
        _ownedTokensIndex[tokenId] = 0;

        _removeTokenFromAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Gets the list of token IDs of the requested owner.
     * @param owner address owning the tokens
     * @return uint256[] List of token IDs owned by the requested address
     */
    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
        return _ownedTokens[owner];
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
        _ownedTokens[to].push(tokenId);
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        _ownedTokens[from].length--;

        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
        // lastTokenId, or just over the end of the array if the token was the last one).
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length.sub(1);
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        _allTokens.length--;
        _allTokensIndex[tokenId] = 0;
    }
}

File 21 of 23: @openzeppelin/contracts/token/ERC721/IERC721.sol
pragma solidity ^0.5.0;

import "../../introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of NFTs in `owner`'s account.
     */
    function balanceOf(address owner) public view returns (uint256 balance);

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApprovalForAll}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApprovalForAll}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

File 22 of 23: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
pragma solidity ^0.5.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a {IERC721-safeTransferFrom}. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

File 23 of 23: @openzeppelin/contracts/introspection/ERC165.sol
pragma solidity ^0.5.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

Contract ABI

[{"constant":true,"inputs":[{"name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cfoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_candidateCEO","type":"address"}],"name":"setCandidateCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ceoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addrs","type":"address[]"}],"name":"removeAddressesFromWhitelist","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setGeneScienceAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"removeAddressFromWhitelist","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCOO","type":"address"}],"name":"setCOO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenID","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCFO","type":"address"}],"name":"setCFO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token_","type":"address"},{"name":"to_","type":"address"},{"name":"amount_","type":"uint256"}],"name":"withdrawTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getAliana","outputs":[{"name":"birthTime","type":"uint256"},{"name":"matronId","type":"uint256"},{"name":"sireId","type":"uint256"},{"name":"genes","type":"uint256"},{"name":"lpLabor","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newContractAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"candidateCEOAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_v2Address","type":"address"}],"name":"setNewAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"addAddressToWhitelist","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"whitelist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"int256"},{"name":"_gene","type":"uint256"}],"name":"geneLpLabor","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_ids","type":"int256[]"},{"name":"_genes","type":"uint256[]"}],"name":"geneLpLabors","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createPromoAliana","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cooAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"}],"name":"mix","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"},{"name":"_genes","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createOfficialAliana","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender_","type":"address"},{"name":"approved_","type":"bool"},{"name":"extraData_","type":"bytes"}],"name":"setApprovalForAllAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createOfficialAliana","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender_","type":"address"},{"name":"tokenId_","type":"uint256"},{"name":"extraData_","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isAliana","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"token_","type":"address"}],"name":"claimTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addrs","type":"address[]"}],"name":"addAddressesToWhitelist","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGeneScienceAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalAlianaSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"alianas","outputs":[{"name":"genes","type":"uint256"},{"name":"birthTime","type":"uint64"},{"name":"matronId","type":"uint64"},{"name":"sireId","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_geneAddr","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"matronId","type":"uint256"},{"indexed":true,"name":"sireId","type":"uint256"},{"indexed":false,"name":"kittenId","type":"uint256"}],"name":"Mix","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"WhitelistedAddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"WhitelistedAddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"SetCandidateCEO","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"AcceptCEO","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"SetCFO","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addr","type":"address"}],"name":"SetCOO","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operator","type":"address"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"operator","type":"address"}],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token_","type":"address"},{"indexed":true,"name":"controller_","type":"address"},{"indexed":false,"name":"amount_","type":"uint256"}],"name":"ClaimedTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token_","type":"address"},{"indexed":true,"name":"controller_","type":"address"},{"indexed":true,"name":"to_","type":"address"},{"indexed":false,"name":"amount_","type":"uint256"}],"name":"WithdrawTokens","type":"event"}]

Contract Creation Code

608060405234801561001057600080fd5b50600436106103275760003560e01c806370a08231116101b8578063b4bb58fb11610104578063d246699d116100a2578063e985e9c51161007c578063e985e9c514610d17578063f129c5d714610d45578063f5834be014610d4d578063f662439914610d5557610327565b8063d246699d14610c7b578063df8de3e714610c83578063e2ec6ec314610ca957610327565b8063c43e1e89116100de578063c43e1e8914610abe578063c87b56dd14610b79578063ca7db95614610b96578063cae9ca5114610bc257610327565b8063b4bb58fb1461099f578063b88d4fde146109c2578063bb96a99c14610a8657610327565b806395d89b4111610171578063a22cb4651161014b578063a22cb4651461087f578063a6ec0430146108ad578063ad31e9b21461096b578063b047fb501461099757610327565b806395d89b411461082e5780639b19251a146108365780639c1941801461085c57610327565b806370a08231146107365780637108cd761461075c57806371587988146107645780637b9417c81461078a5780638456cb59146107b05780638462151c146107b857610327565b80632f745c59116102775780634f6ccce7116102305780636352211e1161020a5780636352211e146106c15780636363bccd146106de5780636af04a57146107265780636c0360eb1461072e57610327565b80634f6ccce7146106665780635c975abb146106835780635e35359e1461068b57610327565b80632f745c59146105b1578063382244f3146105dd5780633f4ba83a146105e557806342842e0e146105ed57806342966c68146106235780634e0a33791461064057610327565b80630a0f8168116102e457806324953eaa116102be57806324953eaa146104d157806324e7a38a1461053f578063286dd3f5146105655780632ba73c151461058b57610327565b80630a0f81681461047957806318160ddd1461048157806323b872dd1461049b57610327565b806301ffc9a71461032c5780630519ce791461036757806306fdde031461038b5780630776c6fb14610408578063081812fc14610430578063095ea7b31461044d575b600080fd5b6103536004803603602081101561034257600080fd5b50356001600160e01b031916610da4565b604080519115158252519081900360200190f35b61036f610dc7565b604080516001600160a01b039092168252519081900360200190f35b610393610dd6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103cd5781810151838201526020016103b5565b50505050905090810190601f1680156103fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61042e6004803603602081101561041e57600080fd5b50356001600160a01b0316610e6d565b005b61036f6004803603602081101561044657600080fd5b5035610f6b565b61042e6004803603604081101561046357600080fd5b506001600160a01b038135169060200135610fd2565b61036f6110fc565b61048961110b565b60408051918252519081900360200190f35b61042e600480360360608110156104b157600080fd5b506001600160a01b03813581169160208101359091169060400135611111565b610353600480360360208110156104e757600080fd5b810190602081018135600160201b81111561050157600080fd5b82018360208201111561051357600080fd5b803590602001918460208302840111600160201b8311171561053457600080fd5b50909250905061116f565b61042e6004803603602081101561055557600080fd5b50356001600160a01b0316611209565b6103536004803603602081101561057b57600080fd5b50356001600160a01b0316611335565b61042e600480360360208110156105a157600080fd5b50356001600160a01b0316611396565b610489600480360360408110156105c757600080fd5b506001600160a01b038135169060200135611494565b61042e611516565b61042e6115d1565b61042e6004803603606081101561060357600080fd5b506001600160a01b038135811691602081013590911690604001356116b8565b61042e6004803603602081101561063957600080fd5b5035611711565b61042e6004803603602081101561065657600080fd5b50356001600160a01b0316611786565b6104896004803603602081101561067c57600080fd5b5035611884565b6103536118ee565b61042e600480360360608110156106a157600080fd5b506001600160a01b038135811691602081013590911690604001356118fe565b61036f600480360360208110156106d757600080fd5b5035611a2b565b6106fb600480360360208110156106f457600080fd5b5035611a84565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b61036f611b78565b610393611b87565b6104896004803603602081101561074c57600080fd5b50356001600160a01b0316611be8565b61036f611c55565b61042e6004803603602081101561077a57600080fd5b50356001600160a01b0316611c64565b610353600480360360208110156107a057600080fd5b50356001600160a01b0316611d5a565b61042e611db5565b6107de600480360360208110156107ce57600080fd5b50356001600160a01b0316611e9d565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561081a578181015183820152602001610802565b505050509050019250505060405180910390f35b610393611efe565b6103536004803603602081101561084c57600080fd5b50356001600160a01b0316611f5f565b6104896004803603604081101561087257600080fd5b5080359060200135611f74565b61042e6004803603604081101561089557600080fd5b506001600160a01b0381351690602001351515611ffd565b6107de600480360360408110156108c357600080fd5b810190602081018135600160201b8111156108dd57600080fd5b8201836020820111156108ef57600080fd5b803590602001918460208302840111600160201b8311171561091057600080fd5b919390929091602081019035600160201b81111561092d57600080fd5b82018360208201111561093f57600080fd5b803590602001918460208302840111600160201b8311171561096057600080fd5b5090925090506120ff565b6104896004803603604081101561098157600080fd5b50803590602001356001600160a01b0316612209565b61036f6122ac565b610489600480360360408110156109b557600080fd5b50803590602001356122bb565b61042e600480360360808110156109d857600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a1257600080fd5b820183602082011115610a2457600080fd5b803590602001918460018302840111600160201b83111715610a4557600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061262e945050505050565b61048960048036036080811015610a9c57600080fd5b50803590602081013590604081013590606001356001600160a01b031661268e565b61035360048036036060811015610ad457600080fd5b6001600160a01b03823516916020810135151591810190606081016040820135600160201b811115610b0557600080fd5b820183602082011115610b1757600080fd5b803590602001918460018302840111600160201b83111715610b3857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612701945050505050565b61039360048036036020811015610b8f57600080fd5b50356127f9565b61048960048036036040811015610bac57600080fd5b50803590602001356001600160a01b03166129ca565b61035360048036036060811015610bd857600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610c0757600080fd5b820183602082011115610c1957600080fd5b803590602001918460018302840111600160201b83111715610c3a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612a3c945050505050565b610353612ac4565b61042e60048036036020811015610c9957600080fd5b50356001600160a01b0316612ac9565b61035360048036036020811015610cbf57600080fd5b810190602081018135600160201b811115610cd957600080fd5b820183602082011115610ceb57600080fd5b803590602001918460208302840111600160201b83111715610d0c57600080fd5b509092509050612c9c565b61035360048036036040811015610d2d57600080fd5b506001600160a01b0381358116916020013516612d2f565b61036f612d5d565b610489612e18565b610d7260048036036020811015610d6b57600080fd5b5035612e1e565b6040805194855267ffffffffffffffff9384166020860152918316848301529091166060830152519081900360800190f35b6001600160e01b0319811660009081526006602052604090205460ff165b919050565b6003546001600160a01b031681565b600f8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e625780601f10610e3757610100808354040283529160200191610e62565b820191906000526020600020905b815481529060010190602001808311610e4557829003601f168201915b505050505090505b90565b6001546001600160a01b03163314610ebc5760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b0381161515610f115760408051600160e51b62461bcd02815260206004820152600f60248201526001608c1b6e0616464722063616e277420626520302604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f55b80fb4511e0b943ccc1f4339e36bb5c0bd9d8907412a7e15b2902740d34192916020908290030190a150565b6000610f7682612e6a565b1515610fb657604051600160e51b62461bcd02815260040180806020018281038252602c81526020018061401d602c913960400191505060405180910390fd5b506000908152600860205260409020546001600160a01b031690565b6000610fdd82611a2b565b90506001600160a01b03838116908216141561102d57604051600160e51b62461bcd0281526004018080602001828103825260218152602001806140a16021913960400191505060405180910390fd5b806001600160a01b031661103f612e87565b6001600160a01b0316148061106057506110608161105b612e87565b612d2f565b15156110a057604051600160e51b62461bcd028152600401808060200182810382526038815260200180613f926038913960400191505060405180910390fd5b60008281526008602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6001546001600160a01b031681565b600d5490565b600454600160a01b900460ff161561115f5760408051600160e51b62461bcd0281526020600482015260066024820152600160d21b651c185d5cd95902604482015290519081900360640190fd5b61116a838383612e8b565b505050565b6001546000906001600160a01b031633146111c15760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b60005b82811015611202576111f08484838181106111db57fe5b905060200201356001600160a01b0316612ee7565b156111fa57600191505b6001016111c4565b5092915050565b6001546001600160a01b031633146112585760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b806001600160a01b03166354c15b826040518163ffffffff1660e01b815260040160206040518083038186803b15801561129157600080fd5b505afa1580156112a5573d6000803e3d6000fd5b505050506040513d60208110156112bb57600080fd5b505115156113135760408051600160e51b62461bcd02815260206004820152601060248201527f416c69616e613a206e6f742067656e6500000000000000000000000000000000604482015290519081900360640190fd5b601380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546000906001600160a01b031633146113875760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b61139082612ee7565b92915050565b6001546001600160a01b031633146113e55760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b038116151561143a5760408051600160e51b62461bcd02815260206004820152600f60248201526001608c1b6e0616464722063616e277420626520302604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517faabebeb2ff97ad067c61c8502e6a2abb9994358e1df40b67dcb61981d5432181916020908290030190a150565b600061149f83611be8565b82106114df57604051600160e51b62461bcd02815260040180806020018281038252602b815260200180613eba602b913960400191505060405180910390fd5b6001600160a01b0383166000908152600b6020526040902080548390811061150357fe5b9060005260206000200154905092915050565b6002546001600160a01b031633146115785760408051600160e51b62461bcd02815260206004820152601960248201527f796f7520617265206e6f74207468652063616e64696461746500000000000000604482015290519081900360640190fd5b600254600180546001600160a01b0319166001600160a01b0392831617908190556040805191909216815290517f47faea4248095943034a5272688739ee6f2c28c2ead4e3584b59a918ae530dac9181900360200190a1565b6001546001600160a01b031633146116205760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b600454600160a01b900460ff1615156116735760408051600160e51b62461bcd02815260206004820152600a6024820152600160b21b691b9bdd081c185d5cd95902604482015290519081900360640190fd5b60048054600160a01b60ff02191690556040805133815290517faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf49181900360200190a1565b600454600160a01b900460ff16156117065760408051600160e51b62461bcd0281526020600482015260066024820152600160d21b651c185d5cd95902604482015290519081900360640190fd5b61116a838383612fb5565b3361171b82611a2b565b6001600160a01b0316146117795760408051600160e51b62461bcd02815260206004820152601960248201527f416c69616e613a206d75737420626520746865206f776e657200000000000000604482015290519081900360640190fd5b6117833382612fd0565b50565b6001546001600160a01b031633146117d55760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b038116151561182a5760408051600160e51b62461bcd02815260206004820152600f60248201526001608c1b6e0616464722063616e277420626520302604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f84b74c5bbb392e2b5031680a6778f6e49e0eed616d7f59d1b7cbe0dc06c814be916020908290030190a150565b600061188e61110b565b82106118ce57604051600160e51b62461bcd02815260040180806020018281038252602c8152602001806140f3602c913960400191505060405180910390fd5b600d8054839081106118dc57fe5b90600052602060002001549050919050565b600454600160a01b900460ff1681565b6001546001600160a01b0316331461194d5760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156119ad57600080fd5b505af11580156119c1573d6000803e3d6000fd5b505050506040513d60208110156119d757600080fd5b505115156119e157fe5b6040805182815290516001600160a01b03808516923392918716917fc9e8848e763791df46dee01dfdd8f0eb58cd33dd15e0773146866af844e8f09b9181900360200190a4505050565b6000818152600760205260408120546001600160a01b031680151561139057604051600160e51b62461bcd028152600401808060200182810382526029815260200180613ff46029913960400191505060405180910390fd5b600080600080600080601487815481101515611a9c57fe5b6000918252602091829020600160029092020190810154815460135460408051600160e71b6301383283028152600481018e905260248101849052905167ffffffffffffffff8086169d50600160401b860481169c50600160801b90950490941699509197509294506001600160a01b0390921692639c1941809260448082019391829003018186803b158015611b3257600080fd5b505afa158015611b46573d6000803e3d6000fd5b505050506040513d6020811015611b5c57600080fd5b505195979496509294919367ffffffffffffffff909216925050565b6005546001600160a01b031681565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e625780601f10610e3757610100808354040283529160200191610e62565b60006001600160a01b0382161515611c3457604051600160e51b62461bcd02815260040180806020018281038252602a815260200180613fca602a913960400191505060405180910390fd5b6001600160a01b03821660009081526009602052604090206113909061301c565b6002546001600160a01b031681565b6001546001600160a01b03163314611cb35760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b600454600160a01b900460ff161515611d065760408051600160e51b62461bcd02815260206004820152600a6024820152600160b21b691b9bdd081c185d5cd95902604482015290519081900360640190fd5b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b6001546000906001600160a01b03163314611dac5760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b61139082613020565b6001546001600160a01b03163314611e045760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b600454600160a01b900460ff1615611e525760408051600160e51b62461bcd0281526020600482015260066024820152600160d21b651c185d5cd95902604482015290519081900360640190fd5b60048054600160a01b60ff021916600160a01b1790556040805133815290517f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca3999181900360200190a1565b6060611ea8826130f2565b805480602002602001604051908101604052809291908181526020018280548015611ef257602002820191906000526020600020905b815481526020019060010190808311611ede575b50505050509050919050565b60108054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610e625780601f10610e3757610100808354040283529160200191610e62565b60006020819052908152604090205460ff1681565b60135460408051600160e71b6301383283028152600481018590526024810184905290516000926001600160a01b031691639c194180916044808301926020929190829003018186803b158015611fca57600080fd5b505afa158015611fde573d6000803e3d6000fd5b505050506040513d6020811015611ff457600080fd5b50519392505050565b612005612e87565b6001600160a01b03838116911614156120685760408051600160e51b62461bcd02815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600a6000612075612e87565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556120b9612e87565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6060808383905060405190808252806020026020018201604052801561212f578160200160208202803883390190505b50905060005b838110156121fd576013546001600160a01b0316639c19418088888481811061215a57fe5b90506020020135878785818110151561216f57fe5b905060200201356040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156121b157600080fd5b505afa1580156121c5573d6000803e3d6000fd5b505050506040513d60208110156121db57600080fd5b505182518390839081106121eb57fe5b60209081029091010152600101612135565b5090505b949350505050565b6004546000906001600160a01b031633148061222f57506001546001600160a01b031633145b8061224457506003546001600160a01b031633145b151561228b5760408051600160e51b62461bcd02815260206004820152600b6024820152600160aa1b6a1b9bdd0818c81b195d995b02604482015290519081900360640190fd5b816001600160a01b038116151561229f5750335b612201600080868461310c565b6004546001600160a01b031681565b600454600090600160a01b900460ff161561230c5760408051600160e51b62461bcd0281526020600482015260066024820152600160d21b651c185d5cd95902604482015290519081900360640190fd5b8282141561234e57604051600160e51b62461bcd02815260040180806020018281038252602b815260200180613f17602b913960400191505060405180910390fd5b3361235884611a2b565b6001600160a01b0316146123b65760408051600160e51b62461bcd02815260206004820152601960248201527f416c69616e613a206d75737420626520746865206f776e657200000000000000604482015290519081900360640190fd5b336123c083611a2b565b6001600160a01b03161461241e5760408051600160e51b62461bcd02815260206004820152601960248201527f416c69616e613a206d75737420626520746865206f776e657200000000000000604482015290519081900360640190fd5b600060148481548110151561242f57fe5b90600052602060002090600202019050600060148481548110151561245057fe5b600091825260209091206001840154600290920201915067ffffffffffffffff1615156124b157604051600160e51b62461bcd028152600401808060200182810382526022815260200180613e986022913960400191505060405180910390fd5b600181015467ffffffffffffffff1615156125165760408051600160e51b62461bcd02815260206004820181905260248201527f416c69616e613a207369726520626972746854696d65206e6f742076616c6964604482015290519081900360640190fd5b6000612520612e18565b6013548454845460408051600160e11b63788a6f5f028152600481018c9052602481018b90526044810193909352606483019190915260848201849052519293506000926001600160a01b039092169163f114debe9160a48082019260209290919082900301818787803b15801561259757600080fd5b505af11580156125ab573d6000803e3d6000fd5b505050506040513d60208110156125c157600080fd5b505190506125cf3388612fd0565b6125d93387612fd0565b60006125e78888843361310c565b60408051828152905191925088918a9133917f4e7c6064fd8f14e28f8a6328ede12db3007ce2347c59bcc79fa0c289aeafd5bf9181900360200190a4979650505050505050565b600454600160a01b900460ff161561267c5760408051600160e51b62461bcd0281526020600482015260066024820152600160d21b651c185d5cd95902604482015290519081900360640190fd5b61268884848484613303565b50505050565b3360009081526020819052604081205460ff1615156126ec5760408051600160e51b62461bcd02815260206004820152600f60248201526001608a1b6e1b9bdd081dda1a5d195b1a5cdd195902604482015290519081900360640190fd5b6126f88585858561310c565b95945050505050565b600061270d8484611ffd565b604051600160e01b638f4ffcb102815233600482018181526000196024840181905230604485018190526080606486019081528751608487015287516001600160a01b038b1696638f4ffcb196958a939092909160a40190602085019080838360005b83811015612788578181015183820152602001612770565b50505050905090810190601f1680156127b55780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156127d757600080fd5b505af11580156127eb573d6000803e3d6000fd5b506001979650505050505050565b606061280482612e6a565b151561284457604051600160e51b62461bcd02815260040180806020018281038252602f815260200180614072602f913960400191505060405180910390fd5b60008281526012602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156128d95780601f106128ae576101008083540402835291602001916128d9565b820191906000526020600020905b8154815290600101906020018083116128bc57829003601f168201915b50505050509050805160001415612900575050604080516020810190915260008152610dc2565b60118160405160200180838054600181600116156101000203166002900480156129615780601f1061293f576101008083540402835291820191612961565b820191906000526020600020905b81548152906001019060200180831161294d575b5050825160208401908083835b6020831061298d5780518252601f19909201916020918201910161296e565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052915050610dc2565b3360009081526020819052604081205460ff161515612a285760408051600160e51b62461bcd02815260206004820152600f60248201526001608a1b6e1b9bdd081dda1a5d195b1a5cdd195902604482015290519081900360640190fd5b612a35600080858561310c565b9392505050565b6000612a488484610fd2565b604051600160e01b638f4ffcb102815233600482018181526024830186905230604484018190526080606485019081528651608486015286516001600160a01b038a1695638f4ffcb195948a94938a939192909160a4909101906020850190808383600083811015612788578181015183820152602001612770565b600190565b6001546001600160a01b03163314612b185760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b0381161515612b5b576040513390303180156108fc02916000818181858888f19350505050158015612b55573d6000803e3d6000fd5b50611783565b60408051600160e01b6370a08231028152306004820152905182916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015612ba957600080fd5b505afa158015612bbd573d6000803e3d6000fd5b505050506040513d6020811015612bd357600080fd5b505160408051600160e01b63a9059cbb0281523360048201526024810183905290519192506001600160a01b0384169163a9059cbb916044808201926020929091908290030181600087803b158015612c2b57600080fd5b505af1158015612c3f573d6000803e3d6000fd5b505050506040513d6020811015612c5557600080fd5b505060408051828152905133916001600160a01b038616917ff931edb47c50b4b4104c187b5814a9aef5f709e17e2ecf9617e860cacade929c9181900360200190a3505050565b6001546000906001600160a01b03163314612cee5760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b60005b8281101561120257612d1d848483818110612d0857fe5b905060200201356001600160a01b0316613020565b15612d2757600191505b600101612cf1565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b6004546000906001600160a01b0316331480612d8357506001546001600160a01b031633145b80612d9857506003546001600160a01b031633145b80612db257503360009081526020819052604090205460ff165b1515612e085760408051600160e51b62461bcd02815260206004820152601a60248201527f6e6f742063206c6576656c206f722077686974656c6973746564000000000000604482015290519081900360640190fd5b506013546001600160a01b031690565b60145490565b6014805482908110612e2c57fe5b60009182526020909120600290910201805460019091015490915067ffffffffffffffff80821691600160401b8104821691600160801b9091041684565b6000908152600760205260409020546001600160a01b0316151590565b3390565b612e9c612e96612e87565b82613360565b1515612edc57604051600160e51b62461bcd0281526004018080602001828103825260318152602001806140c26031913960400191505060405180910390fd5b61116a838383613401565b6001546000906001600160a01b03163314612f395760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b03821660009081526020819052604090205460ff1615610dc2576001600160a01b03821660008181526020818152604091829020805460ff19169055815192835290517ff1abf01a1043b7c244d128e8595cf0c1d10743b022b03a02dffd8ca3bf729f5a9281900390910190a1506001919050565b61116a8383836040518060200160405280600081525061262e565b612fda8282613420565b600081815260126020526040902054600260001961010060018416150201909116041561301857600081815260126020526040812061301891613dee565b5050565b5490565b6001546000906001600160a01b031633146130725760408051600160e51b62461bcd0281526020600482015260076024820152600160c81b666e6f742063656f02604482015290519081900360640190fd5b6001600160a01b03821660009081526020819052604090205460ff161515610dc2576001600160a01b03821660008181526020818152604091829020805460ff19166001179055815192835290517fd1bba68c128cc3f427e5831b3c6f99f480b6efa6b9e80c757768f6124158cc3f9281900390910190a1506001919050565b6001600160a01b03166000908152600b6020526040902090565b60135460145460408051600160e41b630c16b055028152600481019290925260248201859052516000926001600160a01b03169163c16b0550916044808301926020929190829003018186803b15801561316557600080fd5b505afa158015613179573d6000803e3d6000fd5b505050506040513d602081101561318f57600080fd5b505115156131e75760408051600160e51b62461bcd02815260206004820152601960248201527f416c69616e613a2067656e65732069736e27742076616c696400000000000000604482015290519081900360640190fd5b6131ef613e32565b506040805160808101825284815267ffffffffffffffff4281166020830190815288821693830193845287821660608401908152601480546001810182556000919091528451600282027fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec81019190915592517fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ed9093018054965192518516600160801b0277ffffffffffffffff0000000000000000000000000000000019938616600160401b026fffffffffffffffff0000000000000000199590961667ffffffffffffffff199098169790971793909316939093171693909317909255906132f9848261344c565b9695505050505050565b61331461330e612e87565b83613360565b151561335457604051600160e51b62461bcd0281526004018080602001828103825260318152602001806140c26031913960400191505060405180910390fd5b61268884848484613469565b600061336b82612e6a565b15156133ab57604051600160e51b62461bcd02815260040180806020018281038252602c815260200180613f66602c913960400191505060405180910390fd5b60006133b683611a2b565b9050806001600160a01b0316846001600160a01b031614806133f15750836001600160a01b03166133e684610f6b565b6001600160a01b0316145b8061220157506122018185612d2f565b61340c8383836134c0565b613416838261360c565b61116a8282613703565b61342a8282613741565b613434828261360c565b6000818152600c60205260408120556130188161381b565b61345682826138b9565b6134608282613703565b613018816139f2565b613474848484613401565b61348084848484613a36565b151561268857604051600160e51b62461bcd028152600401808060200182810382526032815260200180613ee56032913960400191505060405180910390fd5b826001600160a01b03166134d382611a2b565b6001600160a01b03161461351b57604051600160e51b62461bcd0281526004018080602001828103825260298152602001806140496029913960400191505060405180910390fd5b6001600160a01b038216151561356557604051600160e51b62461bcd028152600401808060200182810382526024815260200180613f426024913960400191505060405180910390fd5b61356e81613c7e565b6001600160a01b038316600090815260096020526040902061358f90613cb9565b6001600160a01b03821660009081526009602052604090206135b090613cd0565b60008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b0382166000908152600b602052604081205461363690600163ffffffff613cd916565b6000838152600c60205260409020549091508082146136d3576001600160a01b0384166000908152600b6020526040812080548490811061367357fe5b9060005260206000200154905080600b6000876001600160a01b03166001600160a01b03168152602001908152602001600020838154811015156136b357fe5b6000918252602080832090910192909255918252600c9052604090208190555b6001600160a01b0384166000908152600b602052604090208054906136fc906000198301613e59565b5050505050565b6001600160a01b039091166000908152600b602081815260408084208054868652600c84529185208290559282526001810183559183529091200155565b816001600160a01b031661375482611a2b565b6001600160a01b03161461379c57604051600160e51b62461bcd02815260040180806020018281038252602581526020018061411f6025913960400191505060405180910390fd5b6137a581613c7e565b6001600160a01b03821660009081526009602052604090206137c690613cb9565b60008181526007602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600d5460009061383290600163ffffffff613cd916565b6000838152600e6020526040812054600d805493945090928490811061385457fe5b9060005260206000200154905080600d8381548110151561387157fe5b6000918252602080832090910192909255828152600e90915260409020829055600d8054906138a4906000198301613e59565b505050600091825250600e6020526040812055565b6001600160a01b03821615156139195760408051600160e51b62461bcd02815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61392281612e6a565b156139775760408051600160e51b62461bcd02815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260076020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600990915290206139b690613cd0565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b6000613a4a846001600160a01b0316613d1b565b1515613a5857506001612201565b600060606001600160a01b038616600160e11b630a85bd0102613a79612e87565b89888860405160240180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613af2578181015183820152602001613ada565b50505050905090810190601f168015613b1f5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909a16999099178952518151919890975087965094509250829150849050835b60208310613b875780518252601f199092019160209182019101613b68565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613be9576040519150601f19603f3d011682016040523d82523d6000602084013e613bee565b606091505b5091509150811515613c4457805115613c0a5780518082602001fd5b604051600160e51b62461bcd028152600401808060200182810382526032815260200180613ee56032913960400191505060405180910390fd5b6000818060200190516020811015613c5b57600080fd5b50516001600160e01b031916600160e11b630a85bd010214935061220192505050565b6000818152600860205260409020546001600160a01b03161561178357600090815260086020526040902080546001600160a01b0319169055565b8054613ccc90600163ffffffff613cd916565b9055565b80546001019055565b6000612a3583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d54565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612201575050151592915050565b60008184841115613de657604051600160e51b62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613dab578181015183820152602001613d93565b50505050905090810190601f168015613dd85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b50805460018160011615610100020316600290046000825580601f10613e145750611783565b601f0160209004906000526020600020908101906117839190613e79565b60408051608081018252600080825260208201819052918101829052606081019190915290565b81548183558181111561116a5760008381526020902061116a9181019083015b610e6a91905b80821115613e935760008155600101613e7f565b509056fe416c69616e613a206d6174726f6e20626972746854696d65206e6f742076616c6964455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e746572416c69616e613a206f6e6c7920646966666572656e7420616c69616e612063616e206265206d65726765644552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776ea165627a7a72305820f4de5d0e6b1082b91ed0aa16f78d3919465ed8ad097c65095c971041922362ab0029

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.