ETH Price: $3,271.36 (+1.63%)
Gas: 3.88 Gwei

Contract

0x706D7F8B3445D8Dfc790C524E3990ef014e7C578
 
Transaction Hash
Method
Block
From
To
Request Release215969442025-01-10 22:03:591 hr ago1736546639IN
Flexa: Staking
0 ETH0.000133465.24514788
Request Release215967682025-01-10 21:28:471 hr ago1736544527IN
Flexa: Staking
0 ETH0.000147965.81233239
Request Release215967622025-01-10 21:27:352 hrs ago1736544455IN
Flexa: Staking
0 ETH0.000137395.39698985
Request Release215959902025-01-10 18:52:594 hrs ago1736535179IN
Flexa: Staking
0 ETH0.000178657.02792221
Request Release215959342025-01-10 18:41:474 hrs ago1736534507IN
Flexa: Staking
0 ETH0.00020948.22589873
Request Release215958372025-01-10 18:22:235 hrs ago1736533343IN
Flexa: Staking
0 ETH0.0002730710.74201395
Request Release215957952025-01-10 18:13:595 hrs ago1736532839IN
Flexa: Staking
0 ETH0.0003013711.83861824
Request Release215956512025-01-10 17:44:595 hrs ago1736531099IN
Flexa: Staking
0 ETH0.000171526.74090926
Request Release215953082025-01-10 16:35:596 hrs ago1736526959IN
Flexa: Staking
0 ETH0.00020267.96993222
Request Release215949332025-01-10 15:20:358 hrs ago1736522435IN
Flexa: Staking
0 ETH0.0006021523.65362866
Request Release215941392025-01-10 12:41:2310 hrs ago1736512883IN
Flexa: Staking
0 ETH0.000136775.37267087
Request Release215939692025-01-10 12:06:5911 hrs ago1736510819IN
Flexa: Staking
0 ETH0.000127375.01044213
Request Release215916292025-01-10 4:15:4719 hrs ago1736482547IN
Flexa: Staking
0 ETH0.000084683.32661829
Request Release215906922025-01-10 1:06:3522 hrs ago1736471195IN
Flexa: Staking
0 ETH0.000115624.54393315
Request Release215906242025-01-10 0:52:5922 hrs ago1736470379IN
Flexa: Staking
0 ETH0.000115834.55004083
Request Release215903822025-01-10 0:04:1123 hrs ago1736467451IN
Flexa: Staking
0 ETH0.00014445.67505237
Request Release215887722025-01-09 18:41:1128 hrs ago1736448071IN
Flexa: Staking
0 ETH0.000202467.95325518
Request Release215886732025-01-09 18:21:2329 hrs ago1736446883IN
Flexa: Staking
0 ETH0.000246999.71141661
Request Release215886482025-01-09 18:16:2329 hrs ago1736446583IN
Flexa: Staking
0 ETH0.0002618710.2917034
Request Release215868932025-01-09 12:22:4735 hrs ago1736425367IN
Flexa: Staking
0 ETH0.000135145.31636508
Request Release215839872025-01-09 2:37:4744 hrs ago1736390267IN
Flexa: Staking
0 ETH0.000142995.62762466
Request Release215836672025-01-09 1:33:2345 hrs ago1736386403IN
Flexa: Staking
0 ETH0.000149845.89183187
Request Release215826252025-01-08 22:04:112 days ago1736373851IN
Flexa: Staking
0 ETH0.000165016.49120654
Request Release215822122025-01-08 20:41:112 days ago1736368871IN
Flexa: Staking
0 ETH0.0002561210.06103024
Request Release215822102025-01-08 20:40:472 days ago1736368847IN
Flexa: Staking
0 ETH0.000238119.35372056
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.