ETH Price: $3,386.53 (+1.23%)

Contract

0x706D7F8B3445D8Dfc790C524E3990ef014e7C578
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Request Release215022762024-12-28 16:51:4721 mins ago1735404707IN
Flexa: Staking
0 ETH0.000178857.02913744
Request Release215020942024-12-28 16:15:2358 mins ago1735402523IN
Flexa: Staking
0 ETH0.000125894.94766446
Request Release215020592024-12-28 16:08:231 hr ago1735402103IN
Flexa: Staking
0 ETH0.000180957.11177481
Request Release215016122024-12-28 14:38:592 hrs ago1735396739IN
Flexa: Staking
0 ETH0.000137075.38711386
Request Release215013672024-12-28 13:49:353 hrs ago1735393775IN
Flexa: Staking
0 ETH0.000127625.01818217
Request Release215004432024-12-28 10:43:476 hrs ago1735382627IN
Flexa: Staking
0 ETH0.000086133.38339965
Request Release215004412024-12-28 10:43:236 hrs ago1735382603IN
Flexa: Staking
0 ETH0.000081453.20105053
Request Release215002982024-12-28 10:14:356 hrs ago1735380875IN
Flexa: Staking
0 ETH0.000095143.74112534
Request Release214996592024-12-28 8:06:239 hrs ago1735373183IN
Flexa: Staking
0 ETH0.000094613.72189334
Request Release214996532024-12-28 8:05:119 hrs ago1735373111IN
Flexa: Staking
0 ETH0.000092713.64197921
Request Release214996502024-12-28 8:04:359 hrs ago1735373075IN
Flexa: Staking
0 ETH0.000095633.75691637
Request Release214996462024-12-28 8:03:479 hrs ago1735373027IN
Flexa: Staking
0 ETH0.000088743.4858975
Request Release214995772024-12-28 7:49:599 hrs ago1735372199IN
Flexa: Staking
0 ETH0.000091733.60847882
Request Release214985202024-12-28 4:17:3512 hrs ago1735359455IN
Flexa: Staking
0 ETH0.000092223.62808154
Request Release214984472024-12-28 4:02:5913 hrs ago1735358579IN
Flexa: Staking
0 ETH0.000076863.01940793
Request Release214983252024-12-28 3:38:2313 hrs ago1735357103IN
Flexa: Staking
0 ETH0.000099143.90379439
Request Release214980402024-12-28 2:41:2314 hrs ago1735353683IN
Flexa: Staking
0 ETH0.000099243.90035594
Request Release214979812024-12-28 2:29:2314 hrs ago1735352963IN
Flexa: Staking
0 ETH0.000095573.75966743
Request Release214978742024-12-28 2:07:5915 hrs ago1735351679IN
Flexa: Staking
0 ETH0.00009243.63165277
Request Release214978122024-12-28 1:55:3515 hrs ago1735350935IN
Flexa: Staking
0 ETH0.000088563.48062917
Request Release214974802024-12-28 0:48:5916 hrs ago1735346939IN
Flexa: Staking
0 ETH0.000110414.33920045
Request Release214970412024-12-27 23:20:3517 hrs ago1735341635IN
Flexa: Staking
0 ETH0.000154086.06416439
Request Release214966812024-12-27 22:07:5919 hrs ago1735337279IN
Flexa: Staking
0 ETH0.000151735.96324662
Request Release214965942024-12-27 21:50:3519 hrs ago1735336235IN
Flexa: Staking
0 ETH0.0001525.98230346
Request Release214964692024-12-27 21:25:2319 hrs ago1735334723IN
Flexa: Staking
0 ETH0.00014085.53357945
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FlexaCollateralManager

Compiler Version
v0.6.10+commit.00c0fcaf

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-08-28
*/

// SPDX-License-Identifier: MIT

pragma solidity 0.6.10;

/**
 * @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.
     */
    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.
     */
    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.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

interface IAmp {
    function registerCollateralManager() external;
}

/**
 * @title Ownable is a contract the provides contract ownership functionality, including a two-
 * phase transfer.
 */
contract Ownable {
    address private _owner;
    address private _authorizedNewOwner;

    /**
     * @notice Emitted when the owner authorizes ownership transfer to a new address
     * @param authorizedAddress New owner address
     */
    event OwnershipTransferAuthorization(address indexed authorizedAddress);

    /**
     * @notice Emitted when the authorized address assumed ownership
     * @param oldValue Old owner
     * @param newValue New owner
     */
    event OwnerUpdate(address indexed oldValue, address indexed newValue);

    /**
     * @notice Sets the owner to the sender / contract creator
     */
    constructor() internal {
        _owner = msg.sender;
    }

    /**
     * @notice Retrieves the owner of the contract
     * @return The contract owner
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @notice Retrieves the authorized new owner of the contract
     * @return The authorized new contract owner
     */
    function authorizedNewOwner() public view returns (address) {
        return _authorizedNewOwner;
    }

    /**
     * @notice Authorizes the transfer of ownership from owner to the provided address.
     * NOTE: No transfer will occur unless authorizedAddress calls assumeOwnership().
     * This authorization may be removed by another call to this function authorizing the zero
     * address.
     * @param _authorizedAddress The address authorized to become the new owner
     */
    function authorizeOwnershipTransfer(address _authorizedAddress) external {
        require(msg.sender == _owner, "Invalid sender");

        _authorizedNewOwner = _authorizedAddress;

        emit OwnershipTransferAuthorization(_authorizedNewOwner);
    }

    /**
     * @notice Transfers ownership of this contract to the _authorizedNewOwner
     * @dev Error invalid sender.
     */
    function assumeOwnership() external {
        require(msg.sender == _authorizedNewOwner, "Invalid sender");

        address oldValue = _owner;
        _owner = _authorizedNewOwner;
        _authorizedNewOwner = address(0);

        emit OwnerUpdate(oldValue, _owner);
    }
}

abstract contract ERC1820Registry {
    function setInterfaceImplementer(
        address _addr,
        bytes32 _interfaceHash,
        address _implementer
    ) external virtual;

    function getInterfaceImplementer(address _addr, bytes32 _interfaceHash)
        external
        virtual
        view
        returns (address);

    function setManager(address _addr, address _newManager) external virtual;

    function getManager(address _addr) public virtual view returns (address);
}

/// Base client to interact with the registry.
contract ERC1820Client {
    ERC1820Registry constant ERC1820REGISTRY = ERC1820Registry(
        0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24
    );

    function setInterfaceImplementation(
        string memory _interfaceLabel,
        address _implementation
    ) internal {
        bytes32 interfaceHash = keccak256(abi.encodePacked(_interfaceLabel));
        ERC1820REGISTRY.setInterfaceImplementer(
            address(this),
            interfaceHash,
            _implementation
        );
    }

    function interfaceAddr(address addr, string memory _interfaceLabel)
        internal
        view
        returns (address)
    {
        bytes32 interfaceHash = keccak256(abi.encodePacked(_interfaceLabel));
        return ERC1820REGISTRY.getInterfaceImplementer(addr, interfaceHash);
    }

    function delegateManagement(address _newManager) internal {
        ERC1820REGISTRY.setManager(address(this), _newManager);
    }
}

/**
 * @title IAmpTokensRecipient
 * @dev IAmpTokensRecipient token transfer hook interface
 */
interface IAmpTokensRecipient {
    /**
     * @dev Report if the recipient will successfully receive the tokens
     */
    function canReceive(
        bytes4 functionSig,
        bytes32 partition,
        address operator,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata operatorData
    ) external view returns (bool);

    /**
     * @dev Hook executed upon a transfer to the recipient
     */
    function tokensReceived(
        bytes4 functionSig,
        bytes32 partition,
        address operator,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata operatorData
    ) external;
}

/**
 * @title IAmpTokensSender
 * @dev IAmpTokensSender token transfer hook interface
 */
interface IAmpTokensSender {
    /**
     * @dev Report if the transfer will succeed from the pespective of the
     * token sender
     */
    function canTransfer(
        bytes4 functionSig,
        bytes32 partition,
        address operator,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata operatorData
    ) external view returns (bool);

    /**
     * @dev Hook executed upon a transfer on behalf of the sender
     */
    function tokensToTransfer(
        bytes4 functionSig,
        bytes32 partition,
        address operator,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata operatorData
    ) external;
}

/**
 * @title PartitionUtils
 * @notice Partition related helper functions.
 */

library PartitionUtils {
    bytes32 public constant CHANGE_PARTITION_FLAG = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /**
     * @notice Retrieve the destination partition from the 'data' field.
     * A partition change is requested ONLY when 'data' starts with the flag:
     *
     *   0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
     *
     * When the flag is detected, the destination partition is extracted from the
     * 32 bytes following the flag.
     * @param _data Information attached to the transfer. Will contain the
     * destination partition if a change is requested.
     * @param _fallbackPartition Partition value to return if a partition change
     * is not requested in the `_data`.
     * @return toPartition Destination partition. If the `_data` does not contain
     * the prefix and bytes32 partition in the first 64 bytes, the method will
     * return the provided `_fromPartition`.
     */
    function _getDestinationPartition(bytes memory _data, bytes32 _fallbackPartition)
        internal
        pure
        returns (bytes32)
    {
        if (_data.length < 64) {
            return _fallbackPartition;
        }

        (bytes32 flag, bytes32 toPartition) = abi.decode(_data, (bytes32, bytes32));
        if (flag == CHANGE_PARTITION_FLAG) {
            return toPartition;
        }

        return _fallbackPartition;
    }

    /**
     * @notice Helper to get the strategy identifying prefix from the `_partition`.
     * @param _partition Partition to get the prefix for.
     * @return 4 byte partition strategy prefix.
     */
    function _getPartitionPrefix(bytes32 _partition) internal pure returns (bytes4) {
        return bytes4(_partition);
    }

    /**
     * @notice Helper method to split the partition into the prefix, sub partition
     * and partition owner components.
     * @param _partition The partition to split into parts.
     * @return The 4 byte partition prefix, 8 byte sub partition, and final 20
     * bytes representing an address.
     */
    function _splitPartition(bytes32 _partition)
        internal
        pure
        returns (
            bytes4,
            bytes8,
            address
        )
    {
        bytes4 prefix = bytes4(_partition);
        bytes8 subPartition = bytes8(_partition << 32);
        address addressPart = address(uint160(uint256(_partition)));
        return (prefix, subPartition, addressPart);
    }

    /**
     * @notice Helper method to get a partition strategy ERC1820 interface name
     * based on partition prefix.
     * @param _prefix 4 byte partition prefix.
     * @dev Each 4 byte prefix has a unique interface name so that an individual
     * hook implementation can be set for each prefix.
     */
    function _getPartitionStrategyValidatorIName(bytes4 _prefix)
        internal
        pure
        returns (string memory)
    {
        return string(abi.encodePacked("AmpPartitionStrategyValidator", _prefix));
    }
}

/**
 * @title FlexaCollateralManager is an implementation of IAmpTokensSender and IAmpTokensRecipient
 * which serves as the Amp collateral manager for the Flexa Network.
 */
contract FlexaCollateralManager is Ownable, IAmpTokensSender, IAmpTokensRecipient, ERC1820Client {
    /**
     * @dev AmpTokensSender interface label.
     */
    string internal constant AMP_TOKENS_SENDER = "AmpTokensSender";

    /**
     * @dev AmpTokensRecipient interface label.
     */
    string internal constant AMP_TOKENS_RECIPIENT = "AmpTokensRecipient";

    /**
     * @dev Change Partition Flag used in transfer data parameters to signal which partition
     * will receive the tokens.
     */
    bytes32
        internal constant CHANGE_PARTITION_FLAG = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /**
     * @dev Required prefix for all registered partitions. Used to ensure the Collateral Pool
     * Partition Validator is used within Amp.
     */
    bytes4 internal constant PARTITION_PREFIX = 0xCCCCCCCC;

    /**********************************************************************************************
     * Operator Data Flags
     *********************************************************************************************/

    /**
     * @dev Flag used in operator data parameters to indicate the transfer is a withdrawal
     */
    bytes32
        internal constant WITHDRAWAL_FLAG = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

    /**
     * @dev Flag used in operator data parameters to indicate the transfer is a fallback
     * withdrawal
     */
    bytes32
        internal constant FALLBACK_WITHDRAWAL_FLAG = 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

    /**
     * @dev Flag used in operator data parameters to indicate the transfer is a supply refund
     */
    bytes32
        internal constant REFUND_FLAG = 0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc;

    /**
     * @dev Flag used in operator data parameters to indicate the transfer is a direct transfer
     */
    bytes32
        internal constant DIRECT_TRANSFER_FLAG = 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd;

    /**********************************************************************************************
     * Configuration
     *********************************************************************************************/

    /**
     * @notice Address of the Amp contract. Immutable.
     */
    address public amp;

    /**
     * @notice Permitted partitions
     */
    mapping(bytes32 => bool) public partitions;

    /**********************************************************************************************
     * Roles
     *********************************************************************************************/

    /**
     * @notice Address authorized to publish withdrawal roots
     */
    address public withdrawalPublisher;

    /**
     * @notice Address authorized to publish fallback withdrawal roots
     */
    address public fallbackPublisher;

    /**
     * @notice Address authorized to adjust the withdrawal limit
     */
    address public withdrawalLimitPublisher;

    /**
     * @notice Address authorized to directly transfer tokens
     */
    address public directTransferer;

    /**
     * @notice Address authorized to manage permitted partition
     */
    address public partitionManager;

    /**
     * @notice Struct used to record received tokens that can be recovered during the fallback
     * withdrawal period
     * @param supplier Token supplier
     * @param partition Partition which received the tokens
     * @param amount Number of tokens received
     */
    struct Supply {
        address supplier;
        bytes32 partition;
        uint256 amount;
    }

    /**********************************************************************************************
     * Supply State
     *********************************************************************************************/

    /**
     * @notice Supply nonce used to track incoming token transfers
     */
    uint256 public supplyNonce = 0;

    /**
     * @notice Mapping of all incoming token transfers
     */
    mapping(uint256 => Supply) public nonceToSupply;

    /**********************************************************************************************
     * Withdrawal State
     *********************************************************************************************/

    /**
     * @notice Remaining withdrawal limit. Initially set to 100,000 Amp.
     */
    uint256 public withdrawalLimit = 100 * 1000 * (10**18);

    /**
     * @notice Withdrawal maximum root nonce
     */
    uint256 public maxWithdrawalRootNonce = 0;

    /**
     * @notice Active set of withdrawal roots
     */
    mapping(bytes32 => uint256) public withdrawalRootToNonce;

    /**
     * @notice Last invoked withdrawal root for each account, per partition
     */
    mapping(bytes32 => mapping(address => uint256)) public addressToWithdrawalNonce;

    /**
     * @notice Total amount withdrawn for each account, per partition
     */
    mapping(bytes32 => mapping(address => uint256)) public addressToCumulativeAmountWithdrawn;

    /**********************************************************************************************
     * Fallback Withdrawal State
     *********************************************************************************************/

    /**
     * @notice Withdrawal fallback delay. Initially set to one week.
     */
    uint256 public fallbackWithdrawalDelaySeconds = 1 weeks;

    /**
     * @notice Current fallback withdrawal root
     */
    bytes32 public fallbackRoot;

    /**
     * @notice Timestamp of when the last fallback root was published
     */
    uint256 public fallbackSetDate = 2**200; // very far in the future

    /**
     * @notice Latest supply reflected in the fallback withdrawal authorization tree
     */
    uint256 public fallbackMaxIncludedSupplyNonce = 0;

    /**********************************************************************************************
     * Supplier Events
     *********************************************************************************************/

    /**
     * @notice Indicates a token supply has been received
     * @param supplier Token supplier
     * @param amount Number of tokens transferred
     * @param nonce Nonce of the supply
     */
    event SupplyReceipt(
        address indexed supplier,
        bytes32 indexed partition,
        uint256 amount,
        uint256 indexed nonce
    );

    /**
     * @notice Indicates that a withdrawal was executed
     * @param supplier Address whose withdrawal authorization was executed
     * @param partition Partition from which the tokens were transferred
     * @param amount Amount of tokens transferred
     * @param rootNonce Nonce of the withdrawal root used for authorization
     * @param authorizedAccountNonce Maximum previous nonce used by the account
     */
    event Withdrawal(
        address indexed supplier,
        bytes32 indexed partition,
        uint256 amount,
        uint256 indexed rootNonce,
        uint256 authorizedAccountNonce
    );

    /**
     * @notice Indicates a fallback withdrawal was executed
     * @param supplier Address whose fallback withdrawal authorization was executed
     * @param partition Partition from which the tokens were transferred
     * @param amount Amount of tokens transferred
     */
    event FallbackWithdrawal(
        address indexed supplier,
        bytes32 indexed partition,
        uint256 indexed amount
    );

    /**
     * @notice Indicates a release of supply is requested
     * @param supplier Token supplier
     * @param partition Parition from which the tokens should be released
     * @param amount Number of tokens requested to be released
     * @param data Metadata provided by the requestor
     */
    event ReleaseRequest(
        address indexed supplier,
        bytes32 indexed partition,
        uint256 indexed amount,
        bytes data
    );

    /**
     * @notice Indicates a supply refund was executed
     * @param supplier Address whose refund authorization was executed
     * @param partition Partition from which the tokens were transferred
     * @param amount Amount of tokens transferred
     * @param nonce Nonce of the original supply
     */
    event SupplyRefund(
        address indexed supplier,
        bytes32 indexed partition,
        uint256 amount,
        uint256 indexed nonce
    );

    /**********************************************************************************************
     * Direct Transfer Events
     *********************************************************************************************/

    /**
     * @notice Emitted when tokens are directly transfered
     * @param operator Address that executed the direct transfer
     * @param from_partition Partition from which the tokens were transferred
     * @param to_address Address to which the tokens were transferred
     * @param to_partition Partition to which the tokens were transferred
     * @param value Amount of tokens transferred
     */
    event DirectTransfer(
        address operator,
        bytes32 indexed from_partition,
        address indexed to_address,
        bytes32 indexed to_partition,
        uint256 value
    );

    /**********************************************************************************************
     * Admin Configuration Events
     *********************************************************************************************/

    /**
     * @notice Emitted when a partition is permitted for supply
     * @param partition Partition added to the permitted set
     */
    event PartitionAdded(bytes32 indexed partition);

    /**
     * @notice Emitted when a partition is removed from the set permitted for supply
     * @param partition Partition removed from the permitted set
     */
    event PartitionRemoved(bytes32 indexed partition);

    /**********************************************************************************************
     * Admin Withdrawal Management Events
     *********************************************************************************************/

    /**
     * @notice Emitted when a new withdrawal root hash is added to the active set
     * @param rootHash Merkle root hash.
     * @param nonce Nonce of the Merkle root hash.
     */
    event WithdrawalRootHashAddition(bytes32 indexed rootHash, uint256 indexed nonce);

    /**
     * @notice Emitted when a withdrawal root hash is removed from the active set
     * @param rootHash Merkle root hash.
     * @param nonce Nonce of the Merkle root hash.
     */
    event WithdrawalRootHashRemoval(bytes32 indexed rootHash, uint256 indexed nonce);

    /**
     * @notice Emitted when the withdrawal limit is updated
     * @param oldValue Old limit.
     * @param newValue New limit.
     */
    event WithdrawalLimitUpdate(uint256 indexed oldValue, uint256 indexed newValue);

    /**********************************************************************************************
     * Admin Fallback Management Events
     *********************************************************************************************/

    /**
     * @notice Emitted when a new fallback withdrawal root hash is set
     * @param rootHash Merkle root hash
     * @param maxSupplyNonceIncluded Nonce of the last supply reflected in the tree data
     * @param setDate Timestamp of when the root hash was set
     */
    event FallbackRootHashSet(
        bytes32 indexed rootHash,
        uint256 indexed maxSupplyNonceIncluded,
        uint256 setDate
    );

    /**
     * @notice Emitted when the fallback root hash set date is reset
     * @param newDate Timestamp of when the fallback reset date was set
     */
    event FallbackMechanismDateReset(uint256 indexed newDate);

    /**
     * @notice Emitted when the fallback delay is updated
     * @param oldValue Old delay
     * @param newValue New delay
     */
    event FallbackWithdrawalDelayUpdate(uint256 indexed oldValue, uint256 indexed newValue);

    /**********************************************************************************************
     * Role Management Events
     *********************************************************************************************/

    /**
     * @notice Emitted when the Withdrawal Publisher is updated
     * @param oldValue Old publisher
     * @param newValue New publisher
     */
    event WithdrawalPublisherUpdate(address indexed oldValue, address indexed newValue);

    /**
     * @notice Emitted when the Fallback Publisher is updated
     * @param oldValue Old publisher
     * @param newValue New publisher
     */
    event FallbackPublisherUpdate(address indexed oldValue, address indexed newValue);

    /**
     * @notice Emitted when Withdrawal Limit Publisher is updated
     * @param oldValue Old publisher
     * @param newValue New publisher
     */
    event WithdrawalLimitPublisherUpdate(address indexed oldValue, address indexed newValue);

    /**
     * @notice Emitted when the DirectTransferer address is updated
     * @param oldValue Old DirectTransferer address
     * @param newValue New DirectTransferer address
     */
    event DirectTransfererUpdate(address indexed oldValue, address indexed newValue);

    /**
     * @notice Emitted when the Partition Manager address is updated
     * @param oldValue Old Partition Manager address
     * @param newValue New Partition Manager address
     */
    event PartitionManagerUpdate(address indexed oldValue, address indexed newValue);

    /**********************************************************************************************
     * Constructor
     *********************************************************************************************/

    /**
     * @notice FlexaCollateralManager constructor
     * @param _amp Address of the Amp token contract
     */
    constructor(address _amp) public {
        amp = _amp;

        ERC1820Client.setInterfaceImplementation(AMP_TOKENS_RECIPIENT, address(this));
        ERC1820Client.setInterfaceImplementation(AMP_TOKENS_SENDER, address(this));

        IAmp(amp).registerCollateralManager();
    }

    /**********************************************************************************************
     * IAmpTokensRecipient Hooks
     *********************************************************************************************/

    /**
     * @notice Validates where the supplied parameters are valid for a transfer of tokens to this
     * contract
     * @dev Implements IAmpTokensRecipient
     * @param _partition Partition from which the tokens were transferred
     * @param _to The destination address of the tokens. Must be this.
     * @param _data Optional data sent with the transfer. Used to set the destination partition.
     * @return true if the tokens can be received, otherwise false
     */
    function canReceive(
        bytes4, /* functionSig */
        bytes32 _partition,
        address, /* operator */
        address, /* from */
        address _to,
        uint256, /* value */
        bytes calldata _data,
        bytes calldata /* operatorData */
    ) external override view returns (bool) {
        if (msg.sender != amp || _to != address(this)) {
            return false;
        }

        bytes32 _destinationPartition = PartitionUtils._getDestinationPartition(_data, _partition);

        return partitions[_destinationPartition];
    }

    /**
     * @notice Function called by the token contract after executing a transfer.
     * @dev Implements IAmpTokensRecipient
     * @param _partition Partition from which the tokens were transferred
     * @param _operator Address which triggered the transfer. This address will be credited with
     * the supply.
     * @param _to The destination address of the tokens. Must be this.
     * @param _value Number of tokens the token holder balance is decreased by.
     * @param _data Optional data sent with the transfer. Used to set the destination partition.
     */
    function tokensReceived(
        bytes4, /* functionSig */
        bytes32 _partition,
        address _operator,
        address, /* from */
        address _to,
        uint256 _value,
        bytes calldata _data,
        bytes calldata /* operatorData */
    ) external override {
        require(msg.sender == amp, "Invalid sender");
        require(_to == address(this), "Invalid to address");

        bytes32 _destinationPartition = PartitionUtils._getDestinationPartition(_data, _partition);

        require(partitions[_destinationPartition], "Invalid destination partition");

        supplyNonce = SafeMath.add(supplyNonce, 1);
        nonceToSupply[supplyNonce].supplier = _operator;
        nonceToSupply[supplyNonce].partition = _destinationPartition;
        nonceToSupply[supplyNonce].amount = _value;

        emit SupplyReceipt(_operator, _destinationPartition, _value, supplyNonce);
    }

    /**********************************************************************************************
     * IAmpTokensSender Hooks
     *********************************************************************************************/

    /**
     * @notice Validates where the supplied parameters are valid for a transfer of tokens from this
     * contract
     * @dev Implements IAmpTokensSender
     * @param _partition Source partition of the tokens
     * @param _operator Address which triggered the transfer
     * @param _from The source address of the tokens. Must be this.
     * @param _value Amount of tokens to be transferred
     * @param _operatorData Extra information attached by the operator. Must include the transfer
     * operation flag and additional authorization data custom for each transfer operation type.
     * @return true if the token transfer would succeed, otherwise false
     */
    function canTransfer(
        bytes4, /*functionSig*/
        bytes32 _partition,
        address _operator,
        address _from,
        address, /* to */
        uint256 _value,
        bytes calldata, /* data */
        bytes calldata _operatorData
    ) external override view returns (bool) {
        if (msg.sender != amp || _from != address(this)) {
            return false;
        }

        bytes32 flag = _decodeOperatorDataFlag(_operatorData);

        if (flag == WITHDRAWAL_FLAG) {
            return _validateWithdrawal(_partition, _operator, _value, _operatorData);
        }
        if (flag == FALLBACK_WITHDRAWAL_FLAG) {
            return _validateFallbackWithdrawal(_partition, _operator, _value, _operatorData);
        }
        if (flag == REFUND_FLAG) {
            return _validateRefund(_partition, _operator, _value, _operatorData);
        }
        if (flag == DIRECT_TRANSFER_FLAG) {
            return _validateDirectTransfer(_operator, _value);
        }

        return false;
    }

    /**
     * @notice Function called by the token contract when executing a transfer
     * @dev Implements IAmpTokensSender
     * @param _partition Source partition of the tokens
     * @param _operator Address which triggered the transfer
     * @param _from The source address of the tokens. Must be this.
     * @param _to The target address of the tokens.
     * @param _value Amount of tokens to be transferred
     * @param _data Data attached to the transfer. Typically includes partition change information.
     * @param _operatorData Extra information attached by the operator. Must include the transfer
     * operation flag and additional authorization data custom for each transfer operation type.
     */
    function tokensToTransfer(
        bytes4, /* functionSig */
        bytes32 _partition,
        address _operator,
        address _from,
        address _to,
        uint256 _value,
        bytes calldata _data,
        bytes calldata _operatorData
    ) external override {
        require(msg.sender == amp, "Invalid sender");
        require(_from == address(this), "Invalid from address");

        bytes32 flag = _decodeOperatorDataFlag(_operatorData);

        if (flag == WITHDRAWAL_FLAG) {
            _executeWithdrawal(_partition, _operator, _value, _operatorData);
        } else if (flag == FALLBACK_WITHDRAWAL_FLAG) {
            _executeFallbackWithdrawal(_partition, _operator, _value, _operatorData);
        } else if (flag == REFUND_FLAG) {
            _executeRefund(_partition, _operator, _value, _operatorData);
        } else if (flag == DIRECT_TRANSFER_FLAG) {
            _executeDirectTransfer(_partition, _operator, _to, _value, _data);
        } else {
            revert("invalid flag");
        }
    }

    /**********************************************************************************************
     * Withdrawals
     *********************************************************************************************/

    /**
     * @notice Validates withdrawal data
     * @param _partition Source partition of the withdrawal
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the withdrawal authorization data
     * @return true if the withdrawal data is valid, otherwise false
     */
    function _validateWithdrawal(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal view returns (bool) {
        (
            address supplier,
            uint256 maxAuthorizedAccountNonce,
            uint256 withdrawalRootNonce
        ) = _getWithdrawalData(_partition, _value, _operatorData);

        return
            _validateWithdrawalData(
                _partition,
                _operator,
                _value,
                supplier,
                maxAuthorizedAccountNonce,
                withdrawalRootNonce
            );
    }

    /**
     * @notice Validates the withdrawal data and updates state to reflect the transfer
     * @param _partition Source partition of the withdrawal
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the withdrawal authorization data
     */
    function _executeWithdrawal(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal {
        (
            address supplier,
            uint256 maxAuthorizedAccountNonce,
            uint256 withdrawalRootNonce
        ) = _getWithdrawalData(_partition, _value, _operatorData);

        require(
            _validateWithdrawalData(
                _partition,
                _operator,
                _value,
                supplier,
                maxAuthorizedAccountNonce,
                withdrawalRootNonce
            ),
            "Transfer unauthorized"
        );

        addressToCumulativeAmountWithdrawn[_partition][supplier] = SafeMath.add(
            _value,
            addressToCumulativeAmountWithdrawn[_partition][supplier]
        );

        addressToWithdrawalNonce[_partition][supplier] = withdrawalRootNonce;

        withdrawalLimit = SafeMath.sub(withdrawalLimit, _value);

        emit Withdrawal(
            supplier,
            _partition,
            _value,
            withdrawalRootNonce,
            maxAuthorizedAccountNonce
        );
    }

    /**
     * @notice Extracts withdrawal data from the supplied parameters
     * @param _partition Source partition of the withdrawal
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the withdrawal authorization data, including the withdrawal
     * operation flag, supplier, maximum authorized account nonce, and Merkle proof.
     * @return supplier, the address whose account is authorized
     * @return maxAuthorizedAccountNonce, the maximum existing used withdrawal nonce for the
     * supplier and partition
     * @return withdrawalRootNonce, the active withdrawal root nonce found based on the supplied
     * data and Merkle proof
     */
    function _getWithdrawalData(
        bytes32 _partition,
        uint256 _value,
        bytes memory _operatorData
    )
        internal
        view
        returns (
            address, /* supplier */
            uint256, /* maxAuthorizedAccountNonce */
            uint256 /* withdrawalRootNonce */
        )
    {
        (
            address supplier,
            uint256 maxAuthorizedAccountNonce,
            bytes32[] memory merkleProof
        ) = _decodeWithdrawalOperatorData(_operatorData);

        bytes32 leafDataHash = _calculateWithdrawalLeaf(
            supplier,
            _partition,
            _value,
            maxAuthorizedAccountNonce
        );

        bytes32 calculatedRoot = _calculateMerkleRoot(merkleProof, leafDataHash);
        uint256 withdrawalRootNonce = withdrawalRootToNonce[calculatedRoot];

        return (supplier, maxAuthorizedAccountNonce, withdrawalRootNonce);
    }

    /**
     * @notice Validates that the parameters are valid for the requested withdrawal
     * @param _partition Source partition of the tokens
     * @param _operator Address that is executing the withdrawal
     * @param _value Number of tokens to be transferred
     * @param _supplier The address whose account is authorized
     * @param _maxAuthorizedAccountNonce The maximum existing used withdrawal nonce for the
     * supplier and partition
     * @param _withdrawalRootNonce The active withdrawal root nonce found based on the supplied
     * data and Merkle proof
     * @return true if the withdrawal data is valid, otherwise false
     */
    function _validateWithdrawalData(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        address _supplier,
        uint256 _maxAuthorizedAccountNonce,
        uint256 _withdrawalRootNonce
    ) internal view returns (bool) {
        return
            // Only owner, withdrawal publisher or supplier can invoke withdrawals
            (_operator == owner() || _operator == withdrawalPublisher || _operator == _supplier) &&
            // Ensure maxAuthorizedAccountNonce has not been exceeded
            (addressToWithdrawalNonce[_partition][_supplier] <= _maxAuthorizedAccountNonce) &&
            // Ensure we are within the global withdrawal limit
            (_value <= withdrawalLimit) &&
            // Merkle tree proof is valid
            (_withdrawalRootNonce > 0) &&
            // Ensure the withdrawal root is more recent than the maxAuthorizedAccountNonce
            (_withdrawalRootNonce > _maxAuthorizedAccountNonce);
    }

    /**********************************************************************************************
     * Fallback Withdrawals
     *********************************************************************************************/

    /**
     * @notice Validates fallback withdrawal data
     * @param _partition Source partition of the withdrawal
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the fallback withdrawal authorization data
     * @return true if the fallback withdrawal data is valid, otherwise false
     */
    function _validateFallbackWithdrawal(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal view returns (bool) {
        (
            address supplier,
            uint256 maxCumulativeWithdrawalAmount,
            uint256 newCumulativeWithdrawalAmount,
            bytes32 calculatedRoot
        ) = _getFallbackWithdrawalData(_partition, _value, _operatorData);

        return
            _validateFallbackWithdrawalData(
                _operator,
                maxCumulativeWithdrawalAmount,
                newCumulativeWithdrawalAmount,
                supplier,
                calculatedRoot
            );
    }

    /**
     * @notice Validates the fallback withdrawal data and updates state to reflect the transfer
     * @param _partition Source partition of the withdrawal
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the fallback withdrawal authorization data
     */
    function _executeFallbackWithdrawal(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal {
        (
            address supplier,
            uint256 maxCumulativeWithdrawalAmount,
            uint256 newCumulativeWithdrawalAmount,
            bytes32 calculatedRoot
        ) = _getFallbackWithdrawalData(_partition, _value, _operatorData);

        require(
            _validateFallbackWithdrawalData(
                _operator,
                maxCumulativeWithdrawalAmount,
                newCumulativeWithdrawalAmount,
                supplier,
                calculatedRoot
            ),
            "Transfer unauthorized"
        );

        addressToCumulativeAmountWithdrawn[_partition][supplier] = newCumulativeWithdrawalAmount;

        addressToWithdrawalNonce[_partition][supplier] = maxWithdrawalRootNonce;

        emit FallbackWithdrawal(supplier, _partition, _value);
    }

    /**
     * @notice Extracts withdrawal data from the supplied parameters
     * @param _partition Source partition of the withdrawal
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the fallback withdrawal authorization data, including the
     * fallback withdrawal operation flag, supplier, max cumulative withdrawal amount, and Merkle
     * proof.
     * @return supplier, the address whose account is authorized
     * @return maxCumulativeWithdrawalAmount, the maximum amount of tokens that can be withdrawn
     * for the supplier's account, including both withdrawals and fallback withdrawals
     * @return newCumulativeWithdrawalAmount, the new total of all withdrawals include the
     * current request
     * @return calculatedRoot, the Merkle tree root calculated based on the supplied data and proof
     */
    function _getFallbackWithdrawalData(
        bytes32 _partition,
        uint256 _value,
        bytes memory _operatorData
    )
        internal
        view
        returns (
            address, /* supplier */
            uint256, /* maxCumulativeWithdrawalAmount */
            uint256, /* newCumulativeWithdrawalAmount */
            bytes32 /* calculatedRoot */
        )
    {
        (
            address supplier,
            uint256 maxCumulativeWithdrawalAmount,
            bytes32[] memory merkleProof
        ) = _decodeWithdrawalOperatorData(_operatorData);

        uint256 newCumulativeWithdrawalAmount = SafeMath.add(
            _value,
            addressToCumulativeAmountWithdrawn[_partition][supplier]
        );

        bytes32 leafDataHash = _calculateFallbackLeaf(
            supplier,
            _partition,
            maxCumulativeWithdrawalAmount
        );
        bytes32 calculatedRoot = _calculateMerkleRoot(merkleProof, leafDataHash);

        return (
            supplier,
            maxCumulativeWithdrawalAmount,
            newCumulativeWithdrawalAmount,
            calculatedRoot
        );
    }

    /**
     * @notice Validates that the parameters are valid for the requested fallback withdrawal
     * @param _operator Address that is executing the withdrawal
     * @param _maxCumulativeWithdrawalAmount, the maximum amount of tokens that can be withdrawn
     * for the supplier's account, including both withdrawals and fallback withdrawals
     * @param _newCumulativeWithdrawalAmount, the new total of all withdrawals include the
     * current request
     * @param _supplier The address whose account is authorized
     * @param _calculatedRoot The Merkle tree root calculated based on the supplied data and proof
     * @return true if the fallback withdrawal data is valid, otherwise false
     */
    function _validateFallbackWithdrawalData(
        address _operator,
        uint256 _maxCumulativeWithdrawalAmount,
        uint256 _newCumulativeWithdrawalAmount,
        address _supplier,
        bytes32 _calculatedRoot
    ) internal view returns (bool) {
        return
            // Only owner or supplier can invoke the fallback withdrawal
            (_operator == owner() || _operator == _supplier) &&
            // Ensure we have entered fallback mode
            (SafeMath.add(fallbackSetDate, fallbackWithdrawalDelaySeconds) <= block.timestamp) &&
            // Check that the maximum allowable withdrawal for the supplier has not been exceeded
            (_newCumulativeWithdrawalAmount <= _maxCumulativeWithdrawalAmount) &&
            // Merkle tree proof is valid
            (fallbackRoot == _calculatedRoot);
    }

    /**********************************************************************************************
     * Supply Refunds
     *********************************************************************************************/

    /**
     * @notice Validates refund data
     * @param _partition Source partition of the refund
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the refund authorization data
     * @return true if the refund data is valid, otherwise false
     */
    function _validateRefund(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal view returns (bool) {
        (uint256 _supplyNonce, Supply memory supply) = _getRefundData(_operatorData);

        return _verifyRefundData(_partition, _operator, _value, _supplyNonce, supply);
    }

    /**
     * @notice Validates the refund data and updates state to reflect the transfer
     * @param _partition Source partition of the refund
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @param _operatorData Contains the refund authorization data
     */
    function _executeRefund(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        bytes memory _operatorData
    ) internal {
        (uint256 nonce, Supply memory supply) = _getRefundData(_operatorData);

        require(
            _verifyRefundData(_partition, _operator, _value, nonce, supply),
            "Transfer unauthorized"
        );

        delete nonceToSupply[nonce];

        emit SupplyRefund(supply.supplier, _partition, supply.amount, nonce);
    }

    /**
     * @notice Extracts refund data from the supplied parameters
     * @param _operatorData Contains the refund authorization data, including the refund
     * operation flag and supply nonce.
     * @return supplyNonce, nonce of the recorded supply
     * @return supply, The supplier, partition and amount of tokens in the original supply
     */
    function _getRefundData(bytes memory _operatorData)
        internal
        view
        returns (uint256, Supply memory)
    {
        uint256 _supplyNonce = _decodeRefundOperatorData(_operatorData);
        Supply memory supply = nonceToSupply[_supplyNonce];

        return (_supplyNonce, supply);
    }

    /**
     * @notice Validates that the parameters are valid for the requested refund
     * @param _partition Source partition of the tokens
     * @param _operator Address that is executing the refund
     * @param _value Number of tokens to be transferred
     * @param _supplyNonce nonce of the recorded supply
     * @param _supply The supplier, partition and amount of tokens in the original supply
     * @return true if the refund data is valid, otherwise false
     */
    function _verifyRefundData(
        bytes32 _partition,
        address _operator,
        uint256 _value,
        uint256 _supplyNonce,
        Supply memory _supply
    ) internal view returns (bool) {
        return
            // Supply record exists
            (_supply.amount > 0) &&
            // Only owner or supplier can invoke the refund
            (_operator == owner() || _operator == _supply.supplier) &&
            // Requested partition matches the Supply record
            (_partition == _supply.partition) &&
            // Requested value matches the Supply record
            (_value == _supply.amount) &&
            // Ensure we have entered fallback mode
            (SafeMath.add(fallbackSetDate, fallbackWithdrawalDelaySeconds) <= block.timestamp) &&
            // Supply has not already been included in the fallback withdrawal data
            (_supplyNonce > fallbackMaxIncludedSupplyNonce);
    }

    /**********************************************************************************************
     * Direct Transfers
     *********************************************************************************************/

    /**
     * @notice Validates direct transfer data
     * @param _operator Address that is invoking the transfer
     * @param _value Number of tokens to be transferred
     * @return true if the direct transfer data is valid, otherwise false
     */
    function _validateDirectTransfer(address _operator, uint256 _value)
        internal
        view
        returns (bool)
    {
        return
            // Only owner and directTransferer can invoke withdrawals
            (_operator == owner() || _operator == directTransferer) &&
            // Ensure we are within the global withdrawal limit
            (_value <= withdrawalLimit);
    }

    /**
     * @notice Validates the direct transfer data and updates state to reflect the transfer
     * @param _partition Source partition of the direct transfer
     * @param _operator Address that is invoking the transfer
     * @param _to The target address of the tokens.
     * @param _value Number of tokens to be transferred
     * @param _data Data attached to the transfer. Typically includes partition change information.
     */
    function _executeDirectTransfer(
        bytes32 _partition,
        address _operator,
        address _to,
        uint256 _value,
        bytes memory _data
    ) internal {
        require(_validateDirectTransfer(_operator, _value), "Transfer unauthorized");

        withdrawalLimit = SafeMath.sub(withdrawalLimit, _value);

        bytes32 to_partition = PartitionUtils._getDestinationPartition(_data, _partition);

        emit DirectTransfer(_operator, _partition, _to, to_partition, _value);
    }

    /**********************************************************************************************
     * Release Request
     *********************************************************************************************/

    /**
     * @notice Emits a release request event that can be used to trigger the release of tokens
     * @param _partition Parition from which the tokens should be released
     * @param _amount Number of tokens requested to be released
     * @param _data Metadata to include with the release request
     */
    function requestRelease(
        bytes32 _partition,
        uint256 _amount,
        bytes memory _data
    ) external {
        emit ReleaseRequest(msg.sender, _partition, _amount, _data);
    }

    /**********************************************************************************************
     * Partition Management
     *********************************************************************************************/

    /**
     * @notice Adds a partition to the set allowed to receive tokens
     * @param _partition Parition to be permitted for incoming transfers
     */
    function addPartition(bytes32 _partition) external {
        require(msg.sender == owner() || msg.sender == partitionManager, "Invalid sender");
        require(partitions[_partition] == false, "Partition already permitted");

        (bytes4 prefix, , address partitionOwner) = PartitionUtils._splitPartition(_partition);

        require(prefix == PARTITION_PREFIX, "Invalid partition prefix");
        require(partitionOwner == address(this), "Invalid partition owner");

        partitions[_partition] = true;

        emit PartitionAdded(_partition);
    }

    /**
     * @notice Removes a partition from the set allowed to receive tokens
     * @param _partition Parition to be disallowed from incoming transfers
     */
    function removePartition(bytes32 _partition) external {
        require(msg.sender == owner() || msg.sender == partitionManager, "Invalid sender");
        require(partitions[_partition], "Partition not permitted");

        delete partitions[_partition];

        emit PartitionRemoved(_partition);
    }

    /**********************************************************************************************
     * Withdrawal Management
     *********************************************************************************************/

    /**
     * @notice Modifies the withdrawal limit by the provided amount.
     * @param _amount Limit delta
     */
    function modifyWithdrawalLimit(int256 _amount) external {
        require(msg.sender == owner() || msg.sender == withdrawalLimitPublisher, "Invalid sender");
        uint256 oldLimit = withdrawalLimit;
        if (_amount < 0) {
            uint256 unsignedAmount = uint256(-_amount);
            withdrawalLimit = SafeMath.sub(withdrawalLimit, unsignedAmount);
        } else {
            uint256 unsignedAmount = uint256(_amount);
            withdrawalLimit = SafeMath.add(withdrawalLimit, unsignedAmount);
        }
        emit WithdrawalLimitUpdate(oldLimit, withdrawalLimit);
    }

    /**
     * @notice Adds the root hash of a Merkle tree containing authorized token withdrawals to the
     * active set
     * @param _root The root hash to be added to the active set
     * @param _nonce The nonce of the new root hash. Must be exactly one higher than the existing
     * max nonce.
     * @param _replacedRoots The root hashes to be removed from the repository.
     */
    function addWithdrawalRoot(
        bytes32 _root,
        uint256 _nonce,
        bytes32[] calldata _replacedRoots
    ) external {
        require(msg.sender == owner() || msg.sender == withdrawalPublisher, "Invalid sender");

        require(_root != 0, "Invalid root");
        require(maxWithdrawalRootNonce + 1 == _nonce, "Nonce not current max plus one");
        require(withdrawalRootToNonce[_root] == 0, "Nonce already used");

        withdrawalRootToNonce[_root] = _nonce;
        maxWithdrawalRootNonce = _nonce;

        emit WithdrawalRootHashAddition(_root, _nonce);

        for (uint256 i = 0; i < _replacedRoots.length; i++) {
            deleteWithdrawalRoot(_replacedRoots[i]);
        }
    }

    /**
     * @notice Removes withdrawal root hashes from active set
     * @param _roots The root hashes to be removed from the active set
     */
    function removeWithdrawalRoots(bytes32[] calldata _roots) external {
        require(msg.sender == owner() || msg.sender == withdrawalPublisher, "Invalid sender");

        for (uint256 i = 0; i < _roots.length; i++) {
            deleteWithdrawalRoot(_roots[i]);
        }
    }

    /**
     * @notice Removes a withdrawal root hash from active set
     * @param _root The root hash to be removed from the active set
     */
    function deleteWithdrawalRoot(bytes32 _root) private {
        uint256 nonce = withdrawalRootToNonce[_root];

        require(nonce > 0, "Root not found");

        delete withdrawalRootToNonce[_root];

        emit WithdrawalRootHashRemoval(_root, nonce);
    }

    /**********************************************************************************************
     * Fallback Management
     *********************************************************************************************/

    /**
     * @notice Sets the root hash of the Merkle tree containing fallback
     * withdrawal authorizations.
     * @param _root The root hash of a Merkle tree containing the fallback withdrawal
     * authorizations
     * @param _maxSupplyNonce The nonce of the latest supply whose value is reflected in the
     * fallback withdrawal authorizations.
     */
    function setFallbackRoot(bytes32 _root, uint256 _maxSupplyNonce) external {
        require(msg.sender == owner() || msg.sender == fallbackPublisher, "Invalid sender");
        require(_root != 0, "Invalid root");
        require(
            SafeMath.add(fallbackSetDate, fallbackWithdrawalDelaySeconds) > block.timestamp,
            "Fallback is active"
        );
        require(
            _maxSupplyNonce >= fallbackMaxIncludedSupplyNonce,
            "Included supply nonce decreased"
        );
        require(_maxSupplyNonce <= supplyNonce, "Included supply nonce exceeds latest supply");

        fallbackRoot = _root;
        fallbackMaxIncludedSupplyNonce = _maxSupplyNonce;
        fallbackSetDate = block.timestamp;

        emit FallbackRootHashSet(_root, fallbackMaxIncludedSupplyNonce, block.timestamp);
    }

    /**
     * @notice Resets the fallback set date to the current block's timestamp. This can be used to
     * delay the start of the fallback period without publishing a new root, or to deactivate the
     * fallback mechanism so a new fallback root may be published.
     */
    function resetFallbackMechanismDate() external {
        require(msg.sender == owner() || msg.sender == fallbackPublisher, "Invalid sender");
        fallbackSetDate = block.timestamp;

        emit FallbackMechanismDateReset(fallbackSetDate);
    }

    /**
     * @notice Updates the time-lock period before the fallback mechanism is activated after the
     * last fallback root was published.
     * @param _newFallbackDelaySeconds The new delay period in seconds
     */
    function setFallbackWithdrawalDelay(uint256 _newFallbackDelaySeconds) external {
        require(msg.sender == owner(), "Invalid sender");
        require(_newFallbackDelaySeconds != 0, "Invalid zero delay seconds");
        require(_newFallbackDelaySeconds < 10 * 365 days, "Invalid delay over 10 years");

        uint256 oldDelay = fallbackWithdrawalDelaySeconds;
        fallbackWithdrawalDelaySeconds = _newFallbackDelaySeconds;

        emit FallbackWithdrawalDelayUpdate(oldDelay, _newFallbackDelaySeconds);
    }

    /**********************************************************************************************
     * Role Management
     *********************************************************************************************/

    /**
     * @notice Updates the Withdrawal Publisher address, the only address other than the owner that
     * can publish / remove withdrawal Merkle tree roots.
     * @param _newWithdrawalPublisher The address of the new Withdrawal Publisher
     * @dev Error invalid sender.
     */
    function setWithdrawalPublisher(address _newWithdrawalPublisher) external {
        require(msg.sender == owner(), "Invalid sender");

        address oldValue = withdrawalPublisher;
        withdrawalPublisher = _newWithdrawalPublisher;

        emit WithdrawalPublisherUpdate(oldValue, withdrawalPublisher);
    }

    /**
     * @notice Updates the Fallback Publisher address, the only address other than the owner that
     * can publish / remove fallback withdrawal Merkle tree roots.
     * @param _newFallbackPublisher The address of the new Fallback Publisher
     * @dev Error invalid sender.
     */
    function setFallbackPublisher(address _newFallbackPublisher) external {
        require(msg.sender == owner(), "Invalid sender");

        address oldValue = fallbackPublisher;
        fallbackPublisher = _newFallbackPublisher;

        emit FallbackPublisherUpdate(oldValue, fallbackPublisher);
    }

    /**
     * @notice Updates the Withdrawal Limit Publisher address, the only address other than the
     * owner that can set the withdrawal limit.
     * @param _newWithdrawalLimitPublisher The address of the new Withdrawal Limit Publisher
     * @dev Error invalid sender.
     */
    function setWithdrawalLimitPublisher(address _newWithdrawalLimitPublisher) external {
        require(msg.sender == owner(), "Invalid sender");

        address oldValue = withdrawalLimitPublisher;
        withdrawalLimitPublisher = _newWithdrawalLimitPublisher;

        emit WithdrawalLimitPublisherUpdate(oldValue, withdrawalLimitPublisher);
    }

    /**
     * @notice Updates the DirectTransferer address, the only address other than the owner that
     * can execute direct transfers
     * @param _newDirectTransferer The address of the new DirectTransferer
     */
    function setDirectTransferer(address _newDirectTransferer) external {
        require(msg.sender == owner(), "Invalid sender");

        address oldValue = directTransferer;
        directTransferer = _newDirectTransferer;

        emit DirectTransfererUpdate(oldValue, directTransferer);
    }

    /**
     * @notice Updates the Partition Manager address, the only address other than the owner that
     * can add and remove permitted partitions
     * @param _newPartitionManager The address of the new PartitionManager
     */
    function setPartitionManager(address _newPartitionManager) external {
        require(msg.sender == owner(), "Invalid sender");

        address oldValue = partitionManager;
        partitionManager = _newPartitionManager;

        emit PartitionManagerUpdate(oldValue, partitionManager);
    }

    /**********************************************************************************************
     * Operator Data Decoders
     *********************************************************************************************/

    /**
     * @notice Extract flag from operatorData
     * @param _operatorData The operator data to be decoded
     * @return flag, the transfer operation type
     */
    function _decodeOperatorDataFlag(bytes memory _operatorData) internal pure returns (bytes32) {
        return abi.decode(_operatorData, (bytes32));
    }

    /**
     * @notice Extracts the supplier, max authorized nonce, and Merkle proof from the operator data
     * @param _operatorData The operator data to be decoded
     * @return supplier, the address whose account is authorized
     * @return For withdrawals: max authorized nonce, the last used withdrawal root nonce for the
     * supplier and partition. For fallback withdrawals: max cumulative withdrawal amount, the
     * maximum amount of tokens that can be withdrawn for the supplier's account, including both
     * withdrawals and fallback withdrawals
     * @return proof, the Merkle proof to be used for the authorization
     */
    function _decodeWithdrawalOperatorData(bytes memory _operatorData)
        internal
        pure
        returns (
            address,
            uint256,
            bytes32[] memory
        )
    {
        (, address supplier, uint256 nonce, bytes32[] memory proof) = abi.decode(
            _operatorData,
            (bytes32, address, uint256, bytes32[])
        );

        return (supplier, nonce, proof);
    }

    /**
     * @notice Extracts the supply nonce from the operator data
     * @param _operatorData The operator data to be decoded
     * @return nonce, the nonce of the supply to be refunded
     */
    function _decodeRefundOperatorData(bytes memory _operatorData) internal pure returns (uint256) {
        (, uint256 nonce) = abi.decode(_operatorData, (bytes32, uint256));

        return nonce;
    }

    /**********************************************************************************************
     * Merkle Tree Verification
     *********************************************************************************************/

    /**
     * @notice Hashes the supplied data and returns the hash to be used in conjunction with a proof
     * to calculate the Merkle tree root
     * @param _supplier The address whose account is authorized
     * @param _partition Source partition of the tokens
     * @param _value Number of tokens to be transferred
     * @param _maxAuthorizedAccountNonce The maximum existing used withdrawal nonce for the
     * supplier and partition
     * @return leaf, the hash of the supplied data
     */
    function _calculateWithdrawalLeaf(
        address _supplier,
        bytes32 _partition,
        uint256 _value,
        uint256 _maxAuthorizedAccountNonce
    ) internal pure returns (bytes32) {
        return
            keccak256(abi.encodePacked(_supplier, _partition, _value, _maxAuthorizedAccountNonce));
    }

    /**
     * @notice Hashes the supplied data and returns the hash to be used in conjunction with a proof
     * to calculate the Merkle tree root
     * @param _supplier The address whose account is authorized
     * @param _partition Source partition of the tokens
     * @param _maxCumulativeWithdrawalAmount, the maximum amount of tokens that can be withdrawn
     * for the supplier's account, including both withdrawals and fallback withdrawals
     * @return leaf, the hash of the supplied data
     */
    function _calculateFallbackLeaf(
        address _supplier,
        bytes32 _partition,
        uint256 _maxCumulativeWithdrawalAmount
    ) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(_supplier, _partition, _maxCumulativeWithdrawalAmount));
    }

    /**
     * @notice Calculates the Merkle root for the unique Merkle tree described by the provided
       Merkle proof and leaf hash.
     * @param _merkleProof The sibling node hashes at each level of the tree.
     * @param _leafHash The hash of the leaf data for which merkleProof is an inclusion proof.
     * @return The calculated Merkle root.
     */
    function _calculateMerkleRoot(bytes32[] memory _merkleProof, bytes32 _leafHash)
        private
        pure
        returns (bytes32)
    {
        bytes32 computedHash = _leafHash;

        for (uint256 i = 0; i < _merkleProof.length; i++) {
            bytes32 proofElement = _merkleProof[i];

            if (computedHash < proofElement) {
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        return computedHash;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_amp","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"bytes32","name":"from_partition","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to_address","type":"address"},{"indexed":true,"internalType":"bytes32","name":"to_partition","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"DirectTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"DirectTransfererUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newDate","type":"uint256"}],"name":"FallbackMechanismDateReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"FallbackPublisherUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"maxSupplyNonceIncluded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"setDate","type":"uint256"}],"name":"FallbackRootHashSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FallbackWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"FallbackWithdrawalDelayUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizedAddress","type":"address"}],"name":"OwnershipTransferAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"}],"name":"PartitionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"PartitionManagerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"}],"name":"PartitionRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ReleaseRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"SupplyReceipt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"SupplyRefund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":true,"internalType":"bytes32","name":"partition","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"rootNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"authorizedAccountNonce","type":"uint256"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"WithdrawalLimitPublisherUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"WithdrawalLimitUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldValue","type":"address"},{"indexed":true,"internalType":"address","name":"newValue","type":"address"}],"name":"WithdrawalPublisherUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"WithdrawalRootHashAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"WithdrawalRootHashRemoval","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_partition","type":"bytes32"}],"name":"addPartition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes32[]","name":"_replacedRoots","type":"bytes32[]"}],"name":"addWithdrawalRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"addressToCumulativeAmountWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"addressToWithdrawalNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assumeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_authorizedAddress","type":"address"}],"name":"authorizeOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authorizedNewOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes32","name":"_partition","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"canReceive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes32","name":"_partition","type":"bytes32"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"_operatorData","type":"bytes"}],"name":"canTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"directTransferer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fallbackMaxIncludedSupplyNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fallbackPublisher","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fallbackRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fallbackSetDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fallbackWithdrawalDelaySeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWithdrawalRootNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"_amount","type":"int256"}],"name":"modifyWithdrawalLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nonceToSupply","outputs":[{"internalType":"address","name":"supplier","type":"address"},{"internalType":"bytes32","name":"partition","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"partitionManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"partitions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_partition","type":"bytes32"}],"name":"removePartition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_roots","type":"bytes32[]"}],"name":"removeWithdrawalRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_partition","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"requestRelease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetFallbackMechanismDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newDirectTransferer","type":"address"}],"name":"setDirectTransferer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFallbackPublisher","type":"address"}],"name":"setFallbackPublisher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_maxSupplyNonce","type":"uint256"}],"name":"setFallbackRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFallbackDelaySeconds","type":"uint256"}],"name":"setFallbackWithdrawalDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPartitionManager","type":"address"}],"name":"setPartitionManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newWithdrawalLimitPublisher","type":"address"}],"name":"setWithdrawalLimitPublisher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newWithdrawalPublisher","type":"address"}],"name":"setWithdrawalPublisher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes32","name":"_partition","type":"bytes32"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"bytes32","name":"_partition","type":"bytes32"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_operatorData","type":"bytes"}],"name":"tokensToTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalLimitPublisher","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalPublisher","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"withdrawalRootToNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6080604052600060095569152d02c7e14af6800000600b556000600c5562093a8060105579010000000000000000000000000000000000000000000000000060125560006013553480156200005357600080fd5b50604051620053fb380380620053fb833981810160405260208110156200007957600080fd5b8101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001576040518060400160405280601281526020017f416d70546f6b656e73526563697069656e740000000000000000000000000000815250306200022e60201b62003c571760201c565b620001a36040518060400160405280600f81526020017f416d70546f6b656e7353656e6465720000000000000000000000000000000000815250306200022e60201b62003c571760201c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9d7b4716040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200020e57600080fd5b505af115801562000223573d6000803e3d6000fd5b505050505062000394565b6000826040516020018082805190602001908083835b6020831062000269578051825260208201915060208101905060208303925062000244565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001209050731820a4b7618bde71dce8cdc73aab6c95905fad2473ffffffffffffffffffffffffffffffffffffffff166329965a1d3083856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b1580156200037657600080fd5b505af11580156200038b573d6000803e3d6000fd5b50505050505050565b61505780620003a46000396000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c80636833403c1161013b5780639363a2a5116100b8578063d445781a1161007c578063d445781a14610ef8578063e44b87f914610f3e578063ec3bb28814610f82578063f18d9a70146110ee578063f24bb1c11461110c57610248565b80639363a2a514610d65578063a2c1cae214610daf578063afa2886414610db9578063c4218e6e14610dfb578063c5cfe77a14610e2957610248565b806387f4427e116100ff57806387f4427e14610c2d578063887ec0b814610c715780638da5cb5b14610cb55780638db1c3ea14610cff5780638e9cdd7d14610d2d57610248565b80636833403c146109f75780636a928f8614610a3b5780637cc17da314610a595780637ddfe78d14610aa35780638240ef4814610ac157610248565b80633a9a7e44116101c95780635481eed31161018d5780635481eed3146108c95780635bc5752a146109135780635d7892801461095d5780635fcf44d1146109bf578063628e46cb146109ed57610248565b80633a9a7e44146107bb5780633b927235146107d957806342592662146107f757806344c545071461083b57806348105b121461088557610248565b80632b15d391116102105780632b15d3911461034b5780632c95e842146103d85780632e47d5e51461045157806330e4cfba146104b357806334c341801461063757610248565b80630780895f1461024d57806308c6345d1461027b5780630973e6ba146102c55780631c8f9a171461030f5780631cef21cf1461032d575b600080fd5b6102796004803603602081101561026357600080fd5b8101908080359060200190929190505050611188565b005b610283611305565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102cd61132b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610317611351565b6040518082815260200191505060405180910390f35b610335611357565b6040518082815260200191505060405180910390f35b6103d66004803603606081101561036157600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561039257600080fd5b8201836020820111156103a457600080fd5b803590602001918460208302840111640100000000831117156103c657600080fd5b909192939192939050505061135d565b005b61044f600480360360208110156103ee57600080fd5b810190808035906020019064010000000081111561040b57600080fd5b82018360208201111561041d57600080fd5b8035906020019184602083028401116401000000008311171561043f57600080fd5b9091929391929390505050611666565b005b61049d6004803603604081101561046757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117a4565b6040518082815260200191505060405180910390f35b61061d60048036036101008110156104ca57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561058457600080fd5b82018360208201111561059657600080fd5b803590602001918460018302840111640100000000831117156105b857600080fd5b9091929391929390803590602001906401000000008111156105d957600080fd5b8201836020820111156105eb57600080fd5b8035906020019184600183028401116401000000008311171561060d57600080fd5b90919293919293905050506117c9565b604051808215151515815260200191505060405180910390f35b6107a1600480360361010081101561064e57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561070857600080fd5b82018360208201111561071a57600080fd5b8035906020019184600183028401116401000000008311171561073c57600080fd5b90919293919293908035906020019064010000000081111561075d57600080fd5b82018360208201111561076f57600080fd5b8035906020019184600183028401116401000000008311171561079157600080fd5b90919293919293905050506118e7565b604051808215151515815260200191505060405180910390f35b6107c3611bab565b6040518082815260200191505060405180910390f35b6107e1611bb1565b6040518082815260200191505060405180910390f35b6108396004803603602081101561080d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611bb7565b005b610843611d47565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108c76004803603602081101561089b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d6d565b005b6108d1611efd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61091b611f27565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109a96004803603604081101561097357600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f4d565b6040518082815260200191505060405180910390f35b6109eb600480360360208110156109d557600080fd5b8101908080359060200190929190505050611f72565b005b6109f56122d6565b005b610a3960048036036020811015610a0d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061240e565b005b610a4361259e565b6040518082815260200191505060405180910390f35b610a616125a4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610aab6125ca565b6040518082815260200191505060405180910390f35b610c2b6004803603610100811015610ad857600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610b9257600080fd5b820183602082011115610ba457600080fd5b80359060200191846001830284011164010000000083111715610bc657600080fd5b909192939192939080359060200190640100000000811115610be757600080fd5b820183602082011115610bf957600080fd5b80359060200191846001830284011164010000000083111715610c1b57600080fd5b90919293919293905050506125d0565b005b610c6f60048036036020811015610c4357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061291c565b005b610cb360048036036020811015610c8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a87565b005b610cbd612c17565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d2b60048036036020811015610d1557600080fd5b8101908080359060200190929190505050612c40565b005b610d6360048036036040811015610d4357600080fd5b810190808035906020019092919080359060200190929190505050612e18565b005b610d6d61313a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610db7613160565b005b610de560048036036020811015610dcf57600080fd5b810190808035906020019092919050505061336b565b6040518082815260200191505060405180910390f35b610e2760048036036020811015610e1157600080fd5b8101908080359060200190929190505050613383565b005b610ef660048036036060811015610e3f57600080fd5b81019080803590602001909291908035906020019092919080359060200190640100000000811115610e7057600080fd5b820183602082011115610e8257600080fd5b80359060200191846001830284011164010000000083111715610ea457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613569565b005b610f2460048036036020811015610f0e57600080fd5b8101908080359060200190929190505050613623565b604051808215151515815260200191505060405180910390f35b610f8060048036036020811015610f5457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613643565b005b6110ec6004803603610100811015610f9957600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561105357600080fd5b82018360208201111561106557600080fd5b8035906020019184600183028401116401000000008311171561108757600080fd5b9091929391929390803590602001906401000000008111156110a857600080fd5b8201836020820111156110ba57600080fd5b803590602001918460018302840111640100000000831117156110dc57600080fd5b90919293919293905050506137d3565b005b6110f6613c07565b6040518082815260200191505060405180910390f35b6111386004803603602081101561112257600080fd5b8101908080359060200190929190505050613c0d565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390f35b611190612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806112165750600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600b54905060008212156112b85760008260000390506112ac600b5482613db9565b600b81905550506112d1565b60008290506112c9600b5482613e03565b600b81905550505b600b54817f35100bc173608e4b64e73420ef31d05adb286a999a3adaeecb20db5a8374096460405160405180910390a35050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60125481565b60105481565b611365612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806113eb5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61145d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801b8414156114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f496e76616c696420726f6f74000000000000000000000000000000000000000081525060200191505060405180910390fd5b826001600c540114611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4e6f6e6365206e6f742063757272656e74206d617820706c7573206f6e65000081525060200191505060405180910390fd5b6000600d600086815260200190815260200160002054146115d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f6e636520616c72656164792075736564000000000000000000000000000081525060200191505060405180910390fd5b82600d60008681526020019081526020016000208190555082600c8190555082847fe03adc1e77ba682eeca70bd85e61002b19d2167914a5c91673b6db229fc9abef60405160405180910390a360008090505b8282905081101561165f5761165283838381811061164657fe5b90506020020135613e8b565b808060010191505061162c565b5050505050565b61166e612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806116f45750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b60008090505b8282905081101561179f5761179283838381811061178657fe5b90506020020135613e8b565b808060010191505061176c565b505050565b600f602052816000526040600020602052806000526040600020600091509150505481565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158061185457503073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b1561186257600090506118d9565b60006118b286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508c613f62565b90506003600082815260200190815260200160002060009054906101000a900460ff169150505b9a9950505050505050505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158061197257503073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b156119805760009050611b9d565b60006119cf84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613fee565b90507faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60001b811415611a5457611a4c8b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061401d565b915050611b9d565b7fbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60001b811415611ad757611acf8b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061404f565b915050611b9d565b7fcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc60001b811415611b5a57611b528b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614085565b915050611b9d565b7fdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd60001b811415611b9757611b8f8a886140b6565b915050611b9d565b60009150505b9a9950505050505050505050565b60135481565b60115481565b611bbf612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7e8156acd1ac1a836d5fa06476cd7c2bd0397675c9caeee22b3c0b969bbebf8c60405160405180910390a35050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d75612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fd2e31556fcf8b4ba79fccb734eaf55dc59bd14b78be000354f6ca30422bbe49a60405160405180910390a35050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e602052816000526040600020602052806000526040600020600091509150505481565b611f7a612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806120005750600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff1615151461210c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f506172746974696f6e20616c7265616479207065726d6974746564000000000081525060200191505060405180910390fd5b6000806121188361415c565b925050915063cccccccc60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146121d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f496e76616c696420706172746974696f6e20707265666978000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612278576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f496e76616c696420706172746974696f6e206f776e657200000000000000000081525060200191505060405180910390fd5b60016003600085815260200190815260200160002060006101000a81548160ff021916908315150217905550827fe0a6f722db02a2a1bda25344bf96d858349b0e5e51b2dfc0189f43c3461c4fa760405160405180910390a2505050565b6122de612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123645750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6123d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b426012819055506012547fbe5d770f5e481394f0304d913c12a7cb92610fb29b382af9f013cc43e53c671260405160405180910390a2565b612416612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146124b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdc4f94b18c0f53480d75b5a6e13d2b2b0414d87603d97d54f383579b8fc107a360405160405180910390a35050565b600c5481565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612693576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614612734576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e76616c696420746f2061646472657373000000000000000000000000000081525060200191505060405180910390fd5b600061278485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b613f62565b90506003600082815260200190815260200160002060009054906101000a900460ff16612819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e76616c69642064657374696e6174696f6e20706172746974696f6e00000081525060200191505060405180910390fd5b6128266009546001613e03565b60098190555088600a6000600954815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a600060095481526020019081526020016000206001018190555085600a6000600954815260200190815260200160002060020181905550600954818a73ffffffffffffffffffffffffffffffffffffffff167fa5521f7d015e07af98ded530ac91a9ccef09b2b0fe09f6a0c8742f40d88e00d1896040518082815260200191505060405180910390a45050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146129de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fb58bcc286020502f4931905baafed22acc969c092ed724234c73361efc68839060405160405180910390a250565b612a8f612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4129b839017b7e303a7a0ca5314793dbb9b6f4f59d12205970967a8a38c10be560405160405180910390a35050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612c48612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000811415612d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c6964207a65726f2064656c6179207365636f6e647300000000000081525060200191505060405180910390fd5b6312cc03008110612dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e76616c69642064656c6179206f766572203130207965617273000000000081525060200191505060405180910390fd5b600060105490508160108190555081817fbcf7cfa26c76f9f5223a62ddebfbc7ef67d6f5cd1ef27147b47cdc11aaae1ef160405160405180910390a35050565b612e20612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612ea65750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801b821415612f91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f496e76616c696420726f6f74000000000000000000000000000000000000000081525060200191505060405180910390fd5b42612fa0601254601054613e03565b11613013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f46616c6c6261636b20697320616374697665000000000000000000000000000081525060200191505060405180910390fd5b60135481101561308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e636c7564656420737570706c79206e6f6e6365206465637265617365640081525060200191505060405180910390fd5b6009548111156130e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614ff7602b913960400191505060405180910390fd5b816011819055508060138190555042601281905550601354827fc838e1d9f03cb7be05349642820d7e002ef8a9a1efc2fbff3292096f6d66dee8426040518082815260200191505060405180910390a35050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a60405160405180910390a350565b600d6020528060005260406000206000915090505481565b61338b612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806134115750600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b613483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6003600082815260200190815260200160002060009054906101000a900460ff16613516576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f506172746974696f6e206e6f74207065726d697474656400000000000000000081525060200191505060405180910390fd5b6003600082815260200190815260200160002060006101000a81549060ff0219169055807f4eebd21e1429831abae9d8bf8c99b5e23567b718371940b6ec713f2c53f5393860405160405180910390a250565b81833373ffffffffffffffffffffffffffffffffffffffff167f1aba60afeb70d9dd8f76ece1c94871b4c3eb1b252b32f58102e21bfb81e944bf846040518080602001828103825283818151815260200191508051906020019080838360005b838110156135e45780820151818401526020810190506135c9565b50505050905090810190601f1680156136115780820380516001836020036101000a031916815260200191505b509250505060405180910390a4505050565b60036020528060005260406000206000915054906101000a900460ff1681565b61364b612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146136eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fd70953def42d9e2d7e243de8cce9cd4ffc14ab08a6090965afe3922f41ae1aa360405160405180910390a35050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614613937576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f496e76616c69642066726f6d206164647265737300000000000000000000000081525060200191505060405180910390fd5b600061398683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613fee565b90507faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60001b811415613a0857613a038a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614189565b613bfa565b7fbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60001b811415613a8857613a838a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614395565b613bf9565b7fcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc60001b811415613b0857613b038a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614528565b613bf8565b7fdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd60001b811415613b8957613b848a8a898989898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061466b565b613bf7565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c696420666c6167000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5b5b5050505050505050505050565b60095481565b600a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154905083565b6000826040516020018082805190602001908083835b60208310613c905780518252602082019150602081019050602083039250613c6d565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001209050731820a4b7618bde71dce8cdc73aab6c95905fad2473ffffffffffffffffffffffffffffffffffffffff166329965a1d3083856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015613d9c57600080fd5b505af1158015613db0573d6000803e3d6000fd5b50505050505050565b6000613dfb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614793565b905092915050565b600080828401905083811015613e81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000600d600083815260200190815260200160002054905060008111613f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f526f6f74206e6f7420666f756e6400000000000000000000000000000000000081525060200191505060405180910390fd5b600d60008381526020019081526020016000206000905580827f8983ad2a9726026394d7a200a18ba3e92f424253ae3eb71d3d8e61dc8e39667c60405160405180910390a35050565b6000604083511015613f7657819050613fe8565b600080848060200190516040811015613f8e57600080fd5b810190808051906020019092919080519060200190929190505050915091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b821415613fe2578092505050613fe8565b83925050505b92915050565b600081806020019051602081101561400557600080fd5b81019080805190602001909291905050509050919050565b60008060008061402e888787614853565b9250925092506140428888888686866148ba565b9350505050949350505050565b6000806000806000614062898888614a0d565b93509350935093506140778884848785614abd565b945050505050949350505050565b600080614090614fbc565b61409984614b68565b915091506140aa8787878585614c1e565b92505050949350505050565b60006140c0612c17565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806141465750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b80156141545750600b548211155b905092915050565b6000806000808490506000602086901b905060008660001c90508282829550955095505050509193909250565b6000806000614199878686614853565b9250925092506141ad8787878686866148ba565b61421f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b61427985600f60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613e03565b600f600089815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600e600089815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061432e600b5486613db9565b600b8190555080878473ffffffffffffffffffffffffffffffffffffffff167f7c05df8754d2754df450658e6ef9fd7bc12dedd9979acddebdd93ac086b424198886604051808381526020018281526020019250505060405180910390a450505050505050565b6000806000806143a6888787614a0d565b93509350935093506143bb8784848785614abd565b61442d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b81600f60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600c54600e60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555085888573ffffffffffffffffffffffffffffffffffffffff167f55ff7b4fbb2c54e7f151ea35b8b6f4b5668e5f1795d2b26fc89fd4d09b1b6de560405160405180910390a45050505050505050565b6000614532614fbc565b61453b83614b68565b9150915061454c8686868585614c1e565b6145be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b600a6000838152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905550508186826000015173ffffffffffffffffffffffffffffffffffffffff167fd3ae64e25cf9949339a5916876c3341a80b5b81eb732da3642a634a7512d180884604001516040518082815260200191505060405180910390a4505050505050565b61467584836140b6565b6146e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b6146f3600b5483613db9565b600b8190555060006147058287613f62565b9050808473ffffffffffffffffffffffffffffffffffffffff16877f4df85043c2fcb97b502fd05c3737899069bb1b523c06beaf6999f3c1f8e5a4b58887604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a4505050505050565b6000838311158290614840576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148055780820151818401526020810190506147ea565b50505050905090810190601f1680156148325780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000806000606061486687614cee565b925092509250600061487a848b8b86614ddc565b905060006148888383614e56565b90506000600d600083815260200190815260200160002054905085858298509850985050505050505093509350939050565b60006148c4612c17565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148061494a5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b8061498057508373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b80156149dc575082600e600089815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411155b80156149ea5750600b548511155b80156149f65750600082115b8015614a0157508282115b90509695505050505050565b6000806000806000806060614a2188614cee565b9250925092506000614a838a600f60008e815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613e03565b90506000614a92858d86614f0c565b90506000614aa08483614e56565b905085858483995099509950995050505050505093509350935093565b6000614ac7612c17565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161480614b2b57508273ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b8015614b44575042614b41601254601054613e03565b11155b8015614b505750848411155b8015614b5d575081601154145b905095945050505050565b6000614b72614fbc565b6000614b7d84614f7d565b9050614b87614fbc565b600a60008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505090508181935093505050915091565b6000808260400151118015614c9f5750614c36612c17565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480614c9e5750816000015173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b5b8015614cae5750816020015186145b8015614cbd5750816040015184145b8015614cd6575042614cd3601254601054613e03565b11155b8015614ce3575060135483115b905095945050505050565b60008060606000806060868060200190516080811015614d0d57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080516040519392919084640100000000821115614d4b57600080fd5b83820191506020820185811115614d6157600080fd5b8251866020820283011164010000000082111715614d7e57600080fd5b8083526020830192505050908051906020019060200280838360005b83811015614db5578082015181840152602081019050614d9a565b50505050905001604052505050935093509350508282829550955095505050509193909250565b600084848484604051602001808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401848152602001838152602001828152602001945050505050604051602081830303815290604052805190602001209050949350505050565b60008082905060008090505b8451811015614f01576000858281518110614e7957fe5b6020026020010151905080831015614ec15782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250614ef3565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b508080600101915050614e62565b508091505092915050565b6000838383604051602001808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182815260200193505050506040516020818303038152906040528051906020012090509392505050565b600080828060200190516040811015614f9557600080fd5b81019080805190602001909291908051906020019092919050505091505080915050919050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000801916815260200160008152509056fe496e636c7564656420737570706c79206e6f6e63652065786365656473206c617465737420737570706c79a26469706673582212207434a8a187fdf6b2bb9d572324a4795d279acd4909615e386e4190bcb0fe3e0764736f6c634300060a0033000000000000000000000000ff20817765cb7f73d4bde2e66e067e58d11095c2

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102485760003560e01c80636833403c1161013b5780639363a2a5116100b8578063d445781a1161007c578063d445781a14610ef8578063e44b87f914610f3e578063ec3bb28814610f82578063f18d9a70146110ee578063f24bb1c11461110c57610248565b80639363a2a514610d65578063a2c1cae214610daf578063afa2886414610db9578063c4218e6e14610dfb578063c5cfe77a14610e2957610248565b806387f4427e116100ff57806387f4427e14610c2d578063887ec0b814610c715780638da5cb5b14610cb55780638db1c3ea14610cff5780638e9cdd7d14610d2d57610248565b80636833403c146109f75780636a928f8614610a3b5780637cc17da314610a595780637ddfe78d14610aa35780638240ef4814610ac157610248565b80633a9a7e44116101c95780635481eed31161018d5780635481eed3146108c95780635bc5752a146109135780635d7892801461095d5780635fcf44d1146109bf578063628e46cb146109ed57610248565b80633a9a7e44146107bb5780633b927235146107d957806342592662146107f757806344c545071461083b57806348105b121461088557610248565b80632b15d391116102105780632b15d3911461034b5780632c95e842146103d85780632e47d5e51461045157806330e4cfba146104b357806334c341801461063757610248565b80630780895f1461024d57806308c6345d1461027b5780630973e6ba146102c55780631c8f9a171461030f5780631cef21cf1461032d575b600080fd5b6102796004803603602081101561026357600080fd5b8101908080359060200190929190505050611188565b005b610283611305565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102cd61132b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610317611351565b6040518082815260200191505060405180910390f35b610335611357565b6040518082815260200191505060405180910390f35b6103d66004803603606081101561036157600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561039257600080fd5b8201836020820111156103a457600080fd5b803590602001918460208302840111640100000000831117156103c657600080fd5b909192939192939050505061135d565b005b61044f600480360360208110156103ee57600080fd5b810190808035906020019064010000000081111561040b57600080fd5b82018360208201111561041d57600080fd5b8035906020019184602083028401116401000000008311171561043f57600080fd5b9091929391929390505050611666565b005b61049d6004803603604081101561046757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117a4565b6040518082815260200191505060405180910390f35b61061d60048036036101008110156104ca57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561058457600080fd5b82018360208201111561059657600080fd5b803590602001918460018302840111640100000000831117156105b857600080fd5b9091929391929390803590602001906401000000008111156105d957600080fd5b8201836020820111156105eb57600080fd5b8035906020019184600183028401116401000000008311171561060d57600080fd5b90919293919293905050506117c9565b604051808215151515815260200191505060405180910390f35b6107a1600480360361010081101561064e57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561070857600080fd5b82018360208201111561071a57600080fd5b8035906020019184600183028401116401000000008311171561073c57600080fd5b90919293919293908035906020019064010000000081111561075d57600080fd5b82018360208201111561076f57600080fd5b8035906020019184600183028401116401000000008311171561079157600080fd5b90919293919293905050506118e7565b604051808215151515815260200191505060405180910390f35b6107c3611bab565b6040518082815260200191505060405180910390f35b6107e1611bb1565b6040518082815260200191505060405180910390f35b6108396004803603602081101561080d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611bb7565b005b610843611d47565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108c76004803603602081101561089b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d6d565b005b6108d1611efd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61091b611f27565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109a96004803603604081101561097357600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f4d565b6040518082815260200191505060405180910390f35b6109eb600480360360208110156109d557600080fd5b8101908080359060200190929190505050611f72565b005b6109f56122d6565b005b610a3960048036036020811015610a0d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061240e565b005b610a4361259e565b6040518082815260200191505060405180910390f35b610a616125a4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610aab6125ca565b6040518082815260200191505060405180910390f35b610c2b6004803603610100811015610ad857600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610b9257600080fd5b820183602082011115610ba457600080fd5b80359060200191846001830284011164010000000083111715610bc657600080fd5b909192939192939080359060200190640100000000811115610be757600080fd5b820183602082011115610bf957600080fd5b80359060200191846001830284011164010000000083111715610c1b57600080fd5b90919293919293905050506125d0565b005b610c6f60048036036020811015610c4357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061291c565b005b610cb360048036036020811015610c8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a87565b005b610cbd612c17565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d2b60048036036020811015610d1557600080fd5b8101908080359060200190929190505050612c40565b005b610d6360048036036040811015610d4357600080fd5b810190808035906020019092919080359060200190929190505050612e18565b005b610d6d61313a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610db7613160565b005b610de560048036036020811015610dcf57600080fd5b810190808035906020019092919050505061336b565b6040518082815260200191505060405180910390f35b610e2760048036036020811015610e1157600080fd5b8101908080359060200190929190505050613383565b005b610ef660048036036060811015610e3f57600080fd5b81019080803590602001909291908035906020019092919080359060200190640100000000811115610e7057600080fd5b820183602082011115610e8257600080fd5b80359060200191846001830284011164010000000083111715610ea457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613569565b005b610f2460048036036020811015610f0e57600080fd5b8101908080359060200190929190505050613623565b604051808215151515815260200191505060405180910390f35b610f8060048036036020811015610f5457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613643565b005b6110ec6004803603610100811015610f9957600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561105357600080fd5b82018360208201111561106557600080fd5b8035906020019184600183028401116401000000008311171561108757600080fd5b9091929391929390803590602001906401000000008111156110a857600080fd5b8201836020820111156110ba57600080fd5b803590602001918460018302840111640100000000831117156110dc57600080fd5b90919293919293905050506137d3565b005b6110f6613c07565b6040518082815260200191505060405180910390f35b6111386004803603602081101561112257600080fd5b8101908080359060200190929190505050613c0d565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390f35b611190612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806112165750600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611288576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600b54905060008212156112b85760008260000390506112ac600b5482613db9565b600b81905550506112d1565b60008290506112c9600b5482613e03565b600b81905550505b600b54817f35100bc173608e4b64e73420ef31d05adb286a999a3adaeecb20db5a8374096460405160405180910390a35050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60125481565b60105481565b611365612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806113eb5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61145d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801b8414156114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f496e76616c696420726f6f74000000000000000000000000000000000000000081525060200191505060405180910390fd5b826001600c540114611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4e6f6e6365206e6f742063757272656e74206d617820706c7573206f6e65000081525060200191505060405180910390fd5b6000600d600086815260200190815260200160002054146115d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f6e636520616c72656164792075736564000000000000000000000000000081525060200191505060405180910390fd5b82600d60008681526020019081526020016000208190555082600c8190555082847fe03adc1e77ba682eeca70bd85e61002b19d2167914a5c91673b6db229fc9abef60405160405180910390a360008090505b8282905081101561165f5761165283838381811061164657fe5b90506020020135613e8b565b808060010191505061162c565b5050505050565b61166e612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806116f45750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b60008090505b8282905081101561179f5761179283838381811061178657fe5b90506020020135613e8b565b808060010191505061176c565b505050565b600f602052816000526040600020602052806000526040600020600091509150505481565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158061185457503073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b1561186257600090506118d9565b60006118b286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508c613f62565b90506003600082815260200190815260200160002060009054906101000a900460ff169150505b9a9950505050505050505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158061197257503073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b156119805760009050611b9d565b60006119cf84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613fee565b90507faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60001b811415611a5457611a4c8b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061401d565b915050611b9d565b7fbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60001b811415611ad757611acf8b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061404f565b915050611b9d565b7fcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc60001b811415611b5a57611b528b8b8987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614085565b915050611b9d565b7fdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd60001b811415611b9757611b8f8a886140b6565b915050611b9d565b60009150505b9a9950505050505050505050565b60135481565b60115481565b611bbf612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7e8156acd1ac1a836d5fa06476cd7c2bd0397675c9caeee22b3c0b969bbebf8c60405160405180910390a35050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611d75612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fd2e31556fcf8b4ba79fccb734eaf55dc59bd14b78be000354f6ca30422bbe49a60405160405180910390a35050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e602052816000526040600020602052806000526040600020600091509150505481565b611f7a612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806120005750600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff1615151461210c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f506172746974696f6e20616c7265616479207065726d6974746564000000000081525060200191505060405180910390fd5b6000806121188361415c565b925050915063cccccccc60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146121d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f496e76616c696420706172746974696f6e20707265666978000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612278576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f496e76616c696420706172746974696f6e206f776e657200000000000000000081525060200191505060405180910390fd5b60016003600085815260200190815260200160002060006101000a81548160ff021916908315150217905550827fe0a6f722db02a2a1bda25344bf96d858349b0e5e51b2dfc0189f43c3461c4fa760405160405180910390a2505050565b6122de612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123645750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6123d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b426012819055506012547fbe5d770f5e481394f0304d913c12a7cb92610fb29b382af9f013cc43e53c671260405160405180910390a2565b612416612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146124b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdc4f94b18c0f53480d75b5a6e13d2b2b0414d87603d97d54f383579b8fc107a360405160405180910390a35050565b600c5481565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612693576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614612734576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e76616c696420746f2061646472657373000000000000000000000000000081525060200191505060405180910390fd5b600061278485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b613f62565b90506003600082815260200190815260200160002060009054906101000a900460ff16612819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e76616c69642064657374696e6174696f6e20706172746974696f6e00000081525060200191505060405180910390fd5b6128266009546001613e03565b60098190555088600a6000600954815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a600060095481526020019081526020016000206001018190555085600a6000600954815260200190815260200160002060020181905550600954818a73ffffffffffffffffffffffffffffffffffffffff167fa5521f7d015e07af98ded530ac91a9ccef09b2b0fe09f6a0c8742f40d88e00d1896040518082815260200191505060405180910390a45050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146129de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fb58bcc286020502f4931905baafed22acc969c092ed724234c73361efc68839060405160405180910390a250565b612a8f612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f4129b839017b7e303a7a0ca5314793dbb9b6f4f59d12205970967a8a38c10be560405160405180910390a35050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612c48612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000811415612d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c6964207a65726f2064656c6179207365636f6e647300000000000081525060200191505060405180910390fd5b6312cc03008110612dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e76616c69642064656c6179206f766572203130207965617273000000000081525060200191505060405180910390fd5b600060105490508160108190555081817fbcf7cfa26c76f9f5223a62ddebfbc7ef67d6f5cd1ef27147b47cdc11aaae1ef160405160405180910390a35050565b612e20612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612ea65750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000801b821415612f91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f496e76616c696420726f6f74000000000000000000000000000000000000000081525060200191505060405180910390fd5b42612fa0601254601054613e03565b11613013576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f46616c6c6261636b20697320616374697665000000000000000000000000000081525060200191505060405180910390fd5b60135481101561308b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e636c7564656420737570706c79206e6f6e6365206465637265617365640081525060200191505060405180910390fd5b6009548111156130e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614ff7602b913960400191505060405180910390fd5b816011819055508060138190555042601281905550601354827fc838e1d9f03cb7be05349642820d7e002ef8a9a1efc2fbff3292096f6d66dee8426040518082815260200191505060405180910390a35050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a60405160405180910390a350565b600d6020528060005260406000206000915090505481565b61338b612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806134115750600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b613483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6003600082815260200190815260200160002060009054906101000a900460ff16613516576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f506172746974696f6e206e6f74207065726d697474656400000000000000000081525060200191505060405180910390fd5b6003600082815260200190815260200160002060006101000a81549060ff0219169055807f4eebd21e1429831abae9d8bf8c99b5e23567b718371940b6ec713f2c53f5393860405160405180910390a250565b81833373ffffffffffffffffffffffffffffffffffffffff167f1aba60afeb70d9dd8f76ece1c94871b4c3eb1b252b32f58102e21bfb81e944bf846040518080602001828103825283818151815260200191508051906020019080838360005b838110156135e45780820151818401526020810190506135c9565b50505050905090810190601f1680156136115780820380516001836020036101000a031916815260200191505b509250505060405180910390a4505050565b60036020528060005260406000206000915054906101000a900460ff1681565b61364b612c17565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146136eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fd70953def42d9e2d7e243de8cce9cd4ffc14ab08a6090965afe3922f41ae1aa360405160405180910390a35050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f496e76616c69642073656e64657200000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614613937576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f496e76616c69642066726f6d206164647265737300000000000000000000000081525060200191505060405180910390fd5b600061398683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613fee565b90507faaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa60001b811415613a0857613a038a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614189565b613bfa565b7fbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60001b811415613a8857613a838a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614395565b613bf9565b7fcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc60001b811415613b0857613b038a8a8886868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614528565b613bf8565b7fdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd60001b811415613b8957613b848a8a898989898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061466b565b613bf7565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c696420666c6167000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5b5b5050505050505050505050565b60095481565b600a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154905083565b6000826040516020018082805190602001908083835b60208310613c905780518252602082019150602081019050602083039250613c6d565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001209050731820a4b7618bde71dce8cdc73aab6c95905fad2473ffffffffffffffffffffffffffffffffffffffff166329965a1d3083856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b158015613d9c57600080fd5b505af1158015613db0573d6000803e3d6000fd5b50505050505050565b6000613dfb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614793565b905092915050565b600080828401905083811015613e81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000600d600083815260200190815260200160002054905060008111613f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f526f6f74206e6f7420666f756e6400000000000000000000000000000000000081525060200191505060405180910390fd5b600d60008381526020019081526020016000206000905580827f8983ad2a9726026394d7a200a18ba3e92f424253ae3eb71d3d8e61dc8e39667c60405160405180910390a35050565b6000604083511015613f7657819050613fe8565b600080848060200190516040811015613f8e57600080fd5b810190808051906020019092919080519060200190929190505050915091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b821415613fe2578092505050613fe8565b83925050505b92915050565b600081806020019051602081101561400557600080fd5b81019080805190602001909291905050509050919050565b60008060008061402e888787614853565b9250925092506140428888888686866148ba565b9350505050949350505050565b6000806000806000614062898888614a0d565b93509350935093506140778884848785614abd565b945050505050949350505050565b600080614090614fbc565b61409984614b68565b915091506140aa8787878585614c1e565b92505050949350505050565b60006140c0612c17565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806141465750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b80156141545750600b548211155b905092915050565b6000806000808490506000602086901b905060008660001c90508282829550955095505050509193909250565b6000806000614199878686614853565b9250925092506141ad8787878686866148ba565b61421f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b61427985600f60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613e03565b600f600089815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600e600089815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061432e600b5486613db9565b600b8190555080878473ffffffffffffffffffffffffffffffffffffffff167f7c05df8754d2754df450658e6ef9fd7bc12dedd9979acddebdd93ac086b424198886604051808381526020018281526020019250505060405180910390a450505050505050565b6000806000806143a6888787614a0d565b93509350935093506143bb8784848785614abd565b61442d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b81600f60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600c54600e60008a815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555085888573ffffffffffffffffffffffffffffffffffffffff167f55ff7b4fbb2c54e7f151ea35b8b6f4b5668e5f1795d2b26fc89fd4d09b1b6de560405160405180910390a45050505050505050565b6000614532614fbc565b61453b83614b68565b9150915061454c8686868585614c1e565b6145be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b600a6000838152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055600282016000905550508186826000015173ffffffffffffffffffffffffffffffffffffffff167fd3ae64e25cf9949339a5916876c3341a80b5b81eb732da3642a634a7512d180884604001516040518082815260200191505060405180910390a4505050505050565b61467584836140b6565b6146e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f5472616e7366657220756e617574686f72697a6564000000000000000000000081525060200191505060405180910390fd5b6146f3600b5483613db9565b600b8190555060006147058287613f62565b9050808473ffffffffffffffffffffffffffffffffffffffff16877f4df85043c2fcb97b502fd05c3737899069bb1b523c06beaf6999f3c1f8e5a4b58887604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a4505050505050565b6000838311158290614840576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156148055780820151818401526020810190506147ea565b50505050905090810190601f1680156148325780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000806000606061486687614cee565b925092509250600061487a848b8b86614ddc565b905060006148888383614e56565b90506000600d600083815260200190815260200160002054905085858298509850985050505050505093509350939050565b60006148c4612c17565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16148061494a5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b8061498057508373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b80156149dc575082600e600089815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411155b80156149ea5750600b548511155b80156149f65750600082115b8015614a0157508282115b90509695505050505050565b6000806000806000806060614a2188614cee565b9250925092506000614a838a600f60008e815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613e03565b90506000614a92858d86614f0c565b90506000614aa08483614e56565b905085858483995099509950995050505050505093509350935093565b6000614ac7612c17565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161480614b2b57508273ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16145b8015614b44575042614b41601254601054613e03565b11155b8015614b505750848411155b8015614b5d575081601154145b905095945050505050565b6000614b72614fbc565b6000614b7d84614f7d565b9050614b87614fbc565b600a60008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505090508181935093505050915091565b6000808260400151118015614c9f5750614c36612c17565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480614c9e5750816000015173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b5b8015614cae5750816020015186145b8015614cbd5750816040015184145b8015614cd6575042614cd3601254601054613e03565b11155b8015614ce3575060135483115b905095945050505050565b60008060606000806060868060200190516080811015614d0d57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080516040519392919084640100000000821115614d4b57600080fd5b83820191506020820185811115614d6157600080fd5b8251866020820283011164010000000082111715614d7e57600080fd5b8083526020830192505050908051906020019060200280838360005b83811015614db5578082015181840152602081019050614d9a565b50505050905001604052505050935093509350508282829550955095505050509193909250565b600084848484604051602001808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401848152602001838152602001828152602001945050505050604051602081830303815290604052805190602001209050949350505050565b60008082905060008090505b8451811015614f01576000858281518110614e7957fe5b6020026020010151905080831015614ec15782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250614ef3565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b508080600101915050614e62565b508091505092915050565b6000838383604051602001808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182815260200193505050506040516020818303038152906040528051906020012090509392505050565b600080828060200190516040811015614f9557600080fd5b81019080805190602001909291908051906020019092919050505091505080915050919050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000801916815260200160008152509056fe496e636c7564656420737570706c79206e6f6e63652065786365656473206c617465737420737570706c79a26469706673582212207434a8a187fdf6b2bb9d572324a4795d279acd4909615e386e4190bcb0fe3e0764736f6c634300060a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000ff20817765cb7f73d4bde2e66e067e58d11095c2

-----Decoded View---------------
Arg [0] : _amp (address): 0xfF20817765cB7f73d4bde2e66e067E58D11095C2

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ff20817765cb7f73d4bde2e66e067e58d11095c2


Deployed Bytecode Sourcemap

14431:55881:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56719:600;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17268:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;16836:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;20276:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;20020:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;57727:734;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;58622:285;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;19596:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29792:578;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;32833:1049;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;20454:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;20151:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;63879:357;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17778:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;64472:301;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6611:105;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;17401:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;19419:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;55292:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61089:254;;;:::i;:::-;;65021:301;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;19144:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;17655:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;19017:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;30966:931;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7112:261;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;63271:308;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6389:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;61581:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;59950:847;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17526:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;7514:282;;;:::i;:::-;;19259:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;56042:312;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;54687:202;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;16918:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;62642:322;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;34625:1059;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;18527:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;18640:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56719:600;56808:7;:5;:7::i;:::-;56794:21;;:10;:21;;;:63;;;;56833:24;;;;;;;;;;;56819:38;;:10;:38;;;56794:63;56786:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56887:16;56906:15;;56887:34;;56946:1;56936:7;:11;56932:316;;;56964:22;56998:7;56997:8;;56964:42;;57039:45;57052:15;;57069:14;57039:12;:45::i;:::-;57021:15;:63;;;;56932:316;;;;57117:22;57150:7;57117:41;;57191:45;57204:15;;57221:14;57191:12;:45::i;:::-;57173:15;:63;;;;56932:316;;57295:15;;57285:8;57263:48;;;;;;;;;;56719:600;;:::o;17268:34::-;;;;;;;;;;;;;:::o;16836:18::-;;;;;;;;;;;;;:::o;20276:39::-;;;;:::o;20020:55::-;;;;:::o;57727:734::-;57896:7;:5;:7::i;:::-;57882:21;;:10;:21;;;:58;;;;57921:19;;;;;;;;;;;57907:33;;:10;:33;;;57882:58;57874:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57989:1;57980:10;;:5;:10;;57972:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58056:6;58051:1;58026:22;;:26;:36;58018:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58148:1;58116:21;:28;58138:5;58116:28;;;;;;;;;;;;:33;58108:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58216:6;58185:21;:28;58207:5;58185:28;;;;;;;;;;;:37;;;;58258:6;58233:22;:31;;;;58316:6;58309:5;58282:41;;;;;;;;;;58341:9;58353:1;58341:13;;58336:118;58360:14;;:21;;58356:1;:25;58336:118;;;58403:39;58424:14;;58439:1;58424:17;;;;;;;;;;;;;58403:20;:39::i;:::-;58383:3;;;;;;;58336:118;;;;57727:734;;;;:::o;58622:285::-;58722:7;:5;:7::i;:::-;58708:21;;:10;:21;;;:58;;;;58747:19;;;;;;;;;;;58733:33;;:10;:33;;;58708:58;58700:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58803:9;58815:1;58803:13;;58798:102;58822:6;;:13;;58818:1;:17;58798:102;;;58857:31;58878:6;;58885:1;58878:9;;;;;;;;;;;;;58857:20;:31::i;:::-;58837:3;;;;;;;58798:102;;;;58622:285;;:::o;19596:89::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;29792:578::-;30104:4;30139:3;;;;;;;;;;;30125:17;;:10;:17;;;;:41;;;;30161:4;30146:20;;:3;:20;;;;30125:41;30121:86;;;30190:5;30183:12;;;;30121:86;30219:29;30251:58;30291:5;;30251:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30298:10;30251:39;:58::i;:::-;30219:90;;30329:10;:33;30340:21;30329:33;;;;;;;;;;;;;;;;;;;;;30322:40;;;29792:578;;;;;;;;;;;;;:::o;32833:1049::-;33134:4;33169:3;;;;;;;;;;;33155:17;;:10;:17;;;;:43;;;;33193:4;33176:22;;:5;:22;;;;33155:43;33151:88;;;33222:5;33215:12;;;;33151:88;33251:12;33266:38;33290:13;;33266:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;:38::i;:::-;33251:53;;15712:66;33329:15;;33321:4;:23;33317:128;;;33368:65;33388:10;33400:9;33411:6;33419:13;;33368:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:19;:65::i;:::-;33361:72;;;;;33317:128;15976:66;33467:24;;33459:4;:32;33455:145;;;33515:73;33543:10;33555:9;33566:6;33574:13;;33515:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:27;:73::i;:::-;33508:80;;;;;33455:145;16213:66;33622:11;;33614:4;:19;33610:120;;;33657:61;33673:10;33685:9;33696:6;33704:13;;33657:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:61::i;:::-;33650:68;;;;;33610:120;16461:66;33752:20;;33744:4;:28;33740:110;;;33796:42;33820:9;33831:6;33796:23;:42::i;:::-;33789:49;;;;;33740:110;33869:5;33862:12;;;32833:1049;;;;;;;;;;;;;:::o;20454:49::-;;;;:::o;20151:27::-;;;;:::o;63879:357::-;63996:7;:5;:7::i;:::-;63982:21;;:10;:21;;;63974:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64035:16;64054:24;;;;;;;;;;;64035:43;;64116:28;64089:24;;:55;;;;;;;;;;;;;;;;;;64203:24;;;;;;;;;;;64162:66;;64193:8;64162:66;;;;;;;;;;;;63879:357;;:::o;17778:31::-;;;;;;;;;;;;;:::o;64472:301::-;64573:7;:5;:7::i;:::-;64559:21;;:10;:21;;;64551:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64612:16;64631;;;;;;;;;;;64612:35;;64677:20;64658:16;;:39;;;;;;;;;;;;;;;;;;64748:16;;;;;;;;;;;64715:50;;64738:8;64715:50;;;;;;;;;;;;64472:301;;:::o;6611:105::-;6662:7;6689:19;;;;;;;;;;;6682:26;;6611:105;:::o;17401:32::-;;;;;;;;;;;;;:::o;19419:79::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;55292:573::-;55376:7;:5;:7::i;:::-;55362:21;;:10;:21;;;:55;;;;55401:16;;;;;;;;;;;55387:30;;:10;:30;;;55362:55;55354:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55481:5;55455:31;;:10;:22;55466:10;55455:22;;;;;;;;;;;;;;;;;;;;;:31;;;55447:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55532:13;55549:22;55575:42;55606:10;55575:30;:42::i;:::-;55531:86;;;;;15298:10;55648:16;;55638:26;;;:6;:26;;;;55630:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55738:4;55712:31;;:14;:31;;;55704:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55809:4;55784:10;:22;55795:10;55784:22;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;55846:10;55831:26;;;;;;;;;;55292:573;;;:::o;61089:254::-;61169:7;:5;:7::i;:::-;61155:21;;:10;:21;;;:56;;;;61194:17;;;;;;;;;;;61180:31;;:10;:31;;;61155:56;61147:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61259:15;61241;:33;;;;61319:15;;61292:43;;;;;;;;;;61089:254::o;65021:301::-;65122:7;:5;:7::i;:::-;65108:21;;:10;:21;;;65100:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65161:16;65180;;;;;;;;;;;65161:35;;65226:20;65207:16;;:39;;;;;;;;;;;;;;;;;;65297:16;;;;;;;;;;;65264:50;;65287:8;65264:50;;;;;;;;;;;;65021:301;;:::o;19144:41::-;;;;:::o;17655:31::-;;;;;;;;;;;;;:::o;19017:54::-;;;;:::o;30966:931::-;31291:3;;;;;;;;;;;31277:17;;:10;:17;;;31269:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31347:4;31332:20;;:3;:20;;;31324:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31388:29;31420:58;31460:5;;31420:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31467:10;31420:39;:58::i;:::-;31388:90;;31499:10;:33;31510:21;31499:33;;;;;;;;;;;;;;;;;;;;;31491:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31593:28;31606:11;;31619:1;31593:12;:28::i;:::-;31579:11;:42;;;;31670:9;31632:13;:26;31646:11;;31632:26;;;;;;;;;;;:35;;;:47;;;;;;;;;;;;;;;;;;31729:21;31690:13;:26;31704:11;;31690:26;;;;;;;;;;;:36;;:60;;;;31797:6;31761:13;:26;31775:11;;31761:26;;;;;;;;;;;:33;;:42;;;;31877:11;;31846:21;31835:9;31821:68;;;31869:6;31821:68;;;;;;;;;;;;;;;;;;30966:931;;;;;;;;;;;:::o;7112:261::-;7218:6;;;;;;;;;;;7204:20;;:10;:20;;;7196:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7278:18;7256:19;;:40;;;;;;;;;;;;;;;;;;7345:19;;;;;;;;;;;7314:51;;;;;;;;;;;;7112:261;:::o;63271:308::-;63374:7;:5;:7::i;:::-;63360:21;;:10;:21;;;63352:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63413:16;63432:17;;;;;;;;;;;63413:36;;63480:21;63460:17;;:41;;;;;;;;;;;;;;;;;;63553:17;;;;;;;;;;;63519:52;;63543:8;63519:52;;;;;;;;;;;;63271:308;;:::o;6389:79::-;6427:7;6454:6;;;;;;;;;;;6447:13;;6389:79;:::o;61581:529::-;61693:7;:5;:7::i;:::-;61679:21;;:10;:21;;;61671:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61766:1;61738:24;:29;;61730:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61844:13;61817:24;:40;61809:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61902:16;61921:30;;61902:49;;61995:24;61962:30;:57;;;;62077:24;62067:8;62037:65;;;;;;;;;;61581:529;;:::o;59950:847::-;60057:7;:5;:7::i;:::-;60043:21;;:10;:21;;;:56;;;;60082:17;;;;;;;;;;;60068:31;;:10;:31;;;60043:56;60035:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60146:1;60137:10;;:5;:10;;60129:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60261:15;60197:61;60210:15;;60227:30;;60197:12;:61::i;:::-;:79;60175:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60374:30;;60355:15;:49;;60333:130;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60501:11;;60482:15;:30;;60474:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60588:5;60573:12;:20;;;;60637:15;60604:30;:48;;;;60681:15;60663;:33;;;;60741:30;;60734:5;60714:75;60773:15;60714:75;;;;;;;;;;;;;;;;;;59950:847;;:::o;17526:39::-;;;;;;;;;;;;;:::o;7514:282::-;7583:19;;;;;;;;;;;7569:33;;:10;:33;;;7561:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7634:16;7653:6;;;;;;;;;;;7634:25;;7679:19;;;;;;;;;;;7670:6;;:28;;;;;;;;;;;;;;;;;;7739:1;7709:19;;:32;;;;;;;;;;;;;;;;;;7781:6;;;;;;;;;;;7759:29;;7771:8;7759:29;;;;;;;;;;;;7514:282;:::o;19259:56::-;;;;;;;;;;;;;;;;;:::o;56042:312::-;56129:7;:5;:7::i;:::-;56115:21;;:10;:21;;;:55;;;;56154:16;;;;;;;;;;;56140:30;;:10;:30;;;56115:55;56107:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56208:10;:22;56219:10;56208:22;;;;;;;;;;;;;;;;;;;;;56200:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56278:10;:22;56289:10;56278:22;;;;;;;;;;;;56271:29;;;;;;;;;;;56335:10;56318:28;;;;;;;;;;56042:312;:::o;54687:202::-;54866:7;54854:10;54842;54827:54;;;54875:5;54827:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54687:202;;;:::o;16918:42::-;;;;;;;;;;;;;;;;;;;;;;:::o;62642:322::-;62749:7;:5;:7::i;:::-;62735:21;;:10;:21;;;62727:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62788:16;62807:19;;;;;;;;;;;62788:38;;62859:23;62837:19;;:45;;;;;;;;;;;;;;;;;;62936:19;;;;;;;;;;;62900:56;;62926:8;62900:56;;;;;;;;;;;;62642:322;;:::o;34625:1059::-;34942:3;;;;;;;;;;;34928:17;;:10;:17;;;34920:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35000:4;34983:22;;:5;:22;;;34975:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35043:12;35058:38;35082:13;;35058:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;:38::i;:::-;35043:53;;15712:66;35121:15;;35113:4;:23;35109:568;;;35153:64;35172:10;35184:9;35195:6;35203:13;;35153:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;:64::i;:::-;35109:568;;;15976:66;35247:24;;35239:4;:32;35235:442;;;35288:72;35315:10;35327:9;35338:6;35346:13;;35288:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:26;:72::i;:::-;35235:442;;;16213:66;35390:11;;35382:4;:19;35378:299;;;35418:60;35433:10;35445:9;35456:6;35464:13;;35418:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;:60::i;:::-;35378:299;;;16461:66;35508:20;;35500:4;:28;35496:181;;;35545:65;35568:10;35580:9;35591:3;35596:6;35604:5;;35545:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;:65::i;:::-;35496:181;;;35643:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35496:181;35378:299;35235:442;35109:568;34625:1059;;;;;;;;;;;:::o;18527:30::-;;;;:::o;18640:47::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;8519:360::-;8656:21;8707:15;8690:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8680:44;;;;;;8656:68;;8461:42;8735:39;;;8797:4;8817:13;8845:15;8735:136;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8519:360;;;:::o;1350:136::-;1408:7;1435:43;1439:1;1442;1435:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1428:50;;1350:136;;;;:::o;894:181::-;952:7;972:9;988:1;984;:5;972:17;;1013:1;1008;:6;;1000:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1066:1;1059:8;;;894:181;;;;:::o;59065:270::-;59129:13;59145:21;:28;59167:5;59145:28;;;;;;;;;;;;59129:44;;59202:1;59194:5;:9;59186:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59242:21;:28;59264:5;59242:28;;;;;;;;;;;59235:35;;;59321:5;59314;59288:39;;;;;;;;;;59065:270;;:::o;12157:455::-;12289:7;12333:2;12318:5;:12;:17;12314:75;;;12359:18;12352:25;;;;12314:75;12402:12;12416:19;12450:5;12439:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12401:75;;;;11234:66;12499:21;;12491:4;:29;12487:80;;;12544:11;12537:18;;;;;;12487:80;12586:18;12579:25;;;;12157:455;;;;;:::o;65741:155::-;65825:7;65863:13;65852:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65845:43;;65741:155;;;:::o;36299:653::-;36477:4;36509:16;36540:33;36588:27;36629:53;36648:10;36660:6;36668:13;36629:18;:53::i;:::-;36494:188;;;;;;36715:229;36757:10;36786:9;36814:6;36839:8;36866:25;36910:19;36715:23;:229::i;:::-;36695:249;;;;;36299:653;;;;;;:::o;42509:721::-;42695:4;42727:16;42758:37;42810;42862:22;42898:61;42925:10;42937:6;42945:13;42898:26;:61::i;:::-;42712:247;;;;;;;;42992:230;43042:9;43070:29;43118;43166:8;43193:14;42992:31;:230::i;:::-;42972:250;;;;;;42509:721;;;;;;:::o;48879:365::-;49053:4;49071:20;49093;;:::i;:::-;49117:29;49132:13;49117:14;:29::i;:::-;49070:76;;;;49166:70;49184:10;49196:9;49207:6;49215:12;49229:6;49166:17;:70::i;:::-;49159:77;;;;48879:365;;;;;;:::o;52748:403::-;52866:4;52993:7;:5;:7::i;:::-;52980:20;;:9;:20;;;:53;;;;53017:16;;;;;;;;;;;53004:29;;:9;:29;;;52980:53;52979:164;;;;;53127:15;;53117:6;:25;;52979:164;52888:255;;52748:403;;;;:::o;13286:408::-;13395:6;13416;13437:7;13472:13;13495:10;13472:34;;13517:19;13560:2;13546:10;:16;;13517:46;;13574:19;13620:10;13612:19;;13574:59;;13652:6;13660:12;13674:11;13644:42;;;;;;;;;13286:408;;;;;:::o;37319:1201::-;37508:16;37539:33;37587:27;37628:53;37647:10;37659:6;37667:13;37628:18;:53::i;:::-;37493:188;;;;;;37716:229;37758:10;37787:9;37815:6;37840:8;37867:25;37911:19;37716:23;:229::i;:::-;37694:300;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38066:115;38093:6;38114:34;:46;38149:10;38114:46;;;;;;;;;;;:56;38161:8;38114:56;;;;;;;;;;;;;;;;38066:12;:115::i;:::-;38007:34;:46;38042:10;38007:46;;;;;;;;;;;:56;38054:8;38007:56;;;;;;;;;;;;;;;:174;;;;38243:19;38194:24;:36;38219:10;38194:36;;;;;;;;;;;:46;38231:8;38194:46;;;;;;;;;;;;;;;:68;;;;38293:37;38306:15;;38323:6;38293:12;:37::i;:::-;38275:15;:55;;;;38442:19;38396:10;38373:8;38348:164;;;38421:6;38476:25;38348:164;;;;;;;;;;;;;;;;;;;;;;;;37319:1201;;;;;;;:::o;43615:1002::-;43812:16;43843:37;43895;43947:22;43983:61;44010:10;44022:6;44030:13;43983:26;:61::i;:::-;43797:247;;;;;;;;44079:230;44129:9;44157:29;44205;44253:8;44280:14;44079:31;:230::i;:::-;44057:301;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44430:29;44371:34;:46;44406:10;44371:46;;;;;;;;;;;:56;44418:8;44371:56;;;;;;;;;;;;;;;:88;;;;44521:22;;44472:24;:36;44497:10;44472:36;;;;;;;;;;;:46;44509:8;44472:46;;;;;;;;;;;;;;;:71;;;;44602:6;44590:10;44580:8;44561:48;;;;;;;;;;;;43615:1002;;;;;;;;:::o;49599:515::-;49770:13;49785:20;;:::i;:::-;49809:29;49824:13;49809:14;:29::i;:::-;49769:69;;;;49873:63;49891:10;49903:9;49914:6;49922:5;49929:6;49873:17;:63::i;:::-;49851:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50005:13;:20;50019:5;50005:20;;;;;;;;;;;;49998:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50100:5;50073:10;50056:6;:15;;;50043:63;;;50085:6;:13;;;50043:63;;;;;;;;;;;;;;;;;;49599:515;;;;;;:::o;53610:520::-;53810:42;53834:9;53845:6;53810:23;:42::i;:::-;53802:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53909:37;53922:15;;53939:6;53909:12;:37::i;:::-;53891:15;:55;;;;53959:20;53982:58;54022:5;54029:10;53982:39;:58::i;:::-;53959:81;;54101:12;54096:3;54058:64;;54084:10;54058:64;54073:9;54115:6;54058:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;53610:520;;;;;;:::o;1781:192::-;1867:7;1900:1;1895;:6;;1903:12;1887:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1927:9;1943:1;1939;:5;1927:17;;1964:1;1957:8;;;1781:192;;;;;:::o;39237:951::-;39427:7;39464;39518;39594:16;39625:33;39673:28;39715:44;39745:13;39715:29;:44::i;:::-;39579:180;;;;;;39772:20;39795:144;39834:8;39857:10;39882:6;39903:25;39795:24;:144::i;:::-;39772:167;;39952:22;39977:47;39998:11;40011:12;39977:20;:47::i;:::-;39952:72;;40035:27;40065:21;:37;40087:14;40065:37;;;;;;;;;;;;40035:67;;40123:8;40133:25;40160:19;40115:65;;;;;;;;;;;;39237:951;;;;;;;:::o;40865:993::-;41122:4;41257:7;:5;:7::i;:::-;41244:20;;:9;:20;;;:56;;;;41281:19;;;;;;;;;;;41268:32;;:9;:32;;;41244:56;:82;;;;41317:9;41304:22;;:9;:22;;;41244:82;41243:251;;;;;41467:26;41416:24;:36;41441:10;41416:36;;;;;;;;;;;:47;41453:9;41416:47;;;;;;;;;;;;;;;;:77;;41243:251;:360;;;;;41587:15;;41577:6;:25;;41243:360;:446;;;;;41687:1;41664:20;:24;41243:446;:607;;;;;41823:26;41800:20;:49;41243:607;41139:711;;40865:993;;;;;;;;:::o;45510:1182::-;45708:7;45745;45803;45861;45932:16;45963:37;46015:28;46057:44;46087:13;46057:29;:44::i;:::-;45917:184;;;;;;46114:37;46154:115;46181:6;46202:34;:46;46237:10;46202:46;;;;;;;;;;;:56;46249:8;46202:56;;;;;;;;;;;;;;;;46154:12;:115::i;:::-;46114:155;;46282:20;46305:125;46342:8;46365:10;46390:29;46305:22;:125::i;:::-;46282:148;;46441:22;46466:47;46487:11;46500:12;46466:20;:47::i;:::-;46441:72;;46548:8;46571:29;46615;46659:14;46526:158;;;;;;;;;;;;;;45510:1182;;;;;;;:::o;47424:853::-;47683:4;47808:7;:5;:7::i;:::-;47795:20;;:9;:20;;;:46;;;;47832:9;47819:22;;:9;:22;;;47795:46;47794:200;;;;;47978:15;47913:61;47926:15;;47943:30;;47913:12;:61::i;:::-;:80;;47794:200;:382;;;;;48145:30;48111;:64;;47794:382;:475;;;;;48253:15;48237:12;;:31;47794:475;47700:569;;47424:853;;;;;;;:::o;50487:316::-;50589:7;50598:13;;:::i;:::-;50629:20;50652:40;50678:13;50652:25;:40::i;:::-;50629:63;;50703:20;;:::i;:::-;50726:13;:27;50740:12;50726:27;;;;;;;;;;;50703:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50774:12;50788:6;50766:29;;;;;;50487:316;;;:::o;51300:951::-;51502:4;51594:1;51577:7;:14;;;:18;51576:153;;;;;51688:7;:5;:7::i;:::-;51675:20;;:9;:20;;;:53;;;;51712:7;:16;;;51699:29;;:9;:29;;;51675:53;51576:153;:265;;;;;51823:7;:17;;;51809:10;:31;51576:265;:366;;;;;51927:7;:14;;;51917:6;:24;51576:366;:518;;;;;52078:15;52013:61;52026:15;;52043:30;;52013:12;:61::i;:::-;:80;;51576:518;:667;;;;;52212:30;;52197:12;:45;51576:667;51519:724;;51300:951;;;;;;;:::o;66561:435::-;66692:7;66714;66736:16;66783;66801:13;66816:22;66867:13;66842:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66780:164;;;;;;;66965:8;66975:5;66982;66957:31;;;;;;;;;66561:435;;;;;:::o;68175:325::-;68366:7;68433:9;68444:10;68456:6;68464:26;68416:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68406:86;;;;;;68386:106;;68175:325;;;;;;:::o;69691:618::-;69820:7;69845:20;69868:9;69845:32;;69895:9;69907:1;69895:13;;69890:380;69914:12;:19;69910:1;:23;69890:380;;;69955:20;69978:12;69991:1;69978:15;;;;;;;;;;;;;;69955:38;;70029:12;70014;:27;70010:249;;;70104:12;70118;70087:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70077:55;;;;;;70062:70;;70010:249;;;70215:12;70229;70198:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70188:55;;;;;;70173:70;;70010:249;69890:380;69935:3;;;;;;;69890:380;;;;70289:12;70282:19;;;69691:618;;;;:::o;69029:285::-;69197:7;69251:9;69262:10;69274:30;69234:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69224:82;;;;;;69217:89;;69029:285;;;;;:::o;67210:204::-;67296:7;67319:13;67347;67336:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67316:65;;;67401:5;67394:12;;;67210:204;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://7434a8a187fdf6b2bb9d572324a4795d279acd4909615e386e4190bcb0fe3e07

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.