ETH Price: $2,088.43 (-3.03%)

Contract

0x4535498CFBeE9C7E2f817d1dF21B2e9e2d9ec9B4
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Unpause238277692025-11-18 18:25:35123 days ago1763490335IN
0x4535498C...e2d9ec9B4
0 ETH0.000064892.33422263
Pause148361512022-05-24 13:58:091397 days ago1653400689IN
0x4535498C...e2d9ec9B4
0 ETH0.00081829.39079589
Unstake148361462022-05-24 13:56:461397 days ago1653400606IN
0x4535498C...e2d9ec9B4
0 ETH0.0013280422.15705963
Unpause148361422022-05-24 13:56:111397 days ago1653400571IN
0x4535498C...e2d9ec9B4
0 ETH0.0006099621.94116948
Migrate ERC20148358842022-05-24 12:57:141397 days ago1653397034IN
0x4535498C...e2d9ec9B4
0 ETH0.0018936635.95681987
Transfer Alloyx ...148310712022-05-23 18:14:591398 days ago1653329699IN
0x4535498C...e2d9ec9B4
0 ETH0.0014778430.22483635
Pause148308482022-05-23 17:22:421398 days ago1653326562IN
0x4535498C...e2d9ec9B4
0 ETH0.0011948842.93216008
Claim Alloyx CRW...147507902022-05-10 20:59:561411 days ago1652216396IN
0x4535498C...e2d9ec9B4
0 ETH0.0046852148.11463593
Claim Reward147005282022-05-02 20:58:511419 days ago1651525131IN
0x4535498C...e2d9ec9B4
0 ETH0.01342854106.11007085
Claim Alloyx CRW...147004792022-05-02 20:45:081419 days ago1651524308IN
0x4535498C...e2d9ec9B4
0 ETH0.0087231489.58211869
Unstake146819832022-04-29 22:54:151422 days ago1651272855IN
0x4535498C...e2d9ec9B4
0 ETH0.0050132861.28566036
Stake146809902022-04-29 19:06:211422 days ago1651259181IN
0x4535498C...e2d9ec9B4
0 ETH0.0056835767.35769426
Deposit USDC Coi...146301502022-04-21 19:25:221430 days ago1650569122IN
0x4535498C...e2d9ec9B4
0 ETH0.0213160864.1029294
Add Whitelisted ...146301382022-04-21 19:22:461430 days ago1650568966IN
0x4535498C...e2d9ec9B4
0 ETH0.0028882862.25817165
Unpause146301282022-04-21 19:20:401430 days ago1650568840IN
0x4535498C...e2d9ec9B4
0 ETH0.0016273458.53751843
Transfer Alloyx ...146295852022-04-21 17:22:461430 days ago1650561766IN
0x4535498C...e2d9ec9B4
0 ETH0.0067537138.12663842
Pause146294762022-04-21 16:56:211430 days ago1650560181IN
0x4535498C...e2d9ec9B4
0 ETH0.002254481.00049676
Start Vault Oper...146286792022-04-21 13:54:091430 days ago1650549249IN
0x4535498C...e2d9ec9B4
0 ETH0.0063092942.44653758
Change Goldfinch...146286282022-04-21 13:45:301430 days ago1650548730IN
0x4535498C...e2d9ec9B4
0 ETH0.0014569250.14185064

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AlloyxVaultV4_0

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2022-04-21
*/

// SPDX-License-Identifier: MIT

// File: alloyx-smart-contracts-v2/contracts/goldfinch/interfaces/ICreditLine.sol



pragma solidity ^0.8.7;
pragma experimental ABIEncoderV2;

interface ICreditLine {
  function borrower() external view returns (address);

  function limit() external view returns (uint256);

  function maxLimit() external view returns (uint256);

  function interestApr() external view returns (uint256);

  function paymentPeriodInDays() external view returns (uint256);

  function principalGracePeriodInDays() external view returns (uint256);

  function termInDays() external view returns (uint256);

  function lateFeeApr() external view returns (uint256);

  function isLate() external view returns (bool);

  function withinPrincipalGracePeriod() external view returns (bool);

  // Accounting variables
  function balance() external view returns (uint256);

  function interestOwed() external view returns (uint256);

  function principalOwed() external view returns (uint256);

  function termEndTime() external view returns (uint256);

  function nextDueTime() external view returns (uint256);

  function interestAccruedAsOf() external view returns (uint256);

  function lastFullPaymentTime() external view returns (uint256);
}

// File: alloyx-smart-contracts-v2/contracts/goldfinch/interfaces/IV2CreditLine.sol


pragma solidity ^0.8.7;


abstract contract IV2CreditLine is ICreditLine {
  function principal() external view virtual returns (uint256);

  function totalInterestAccrued() external view virtual returns (uint256);

  function termStartTime() external view virtual returns (uint256);

  function setLimit(uint256 newAmount) external virtual;

  function setMaxLimit(uint256 newAmount) external virtual;

  function setBalance(uint256 newBalance) external virtual;

  function setPrincipal(uint256 _principal) external virtual;

  function setTotalInterestAccrued(uint256 _interestAccrued) external virtual;

  function drawdown(uint256 amount) external virtual;

  function assess()
    external
    virtual
    returns (
      uint256,
      uint256,
      uint256
    );

  function initialize(
    address _config,
    address owner,
    address _borrower,
    uint256 _limit,
    uint256 _interestApr,
    uint256 _paymentPeriodInDays,
    uint256 _termInDays,
    uint256 _lateFeeApr,
    uint256 _principalGracePeriodInDays
  ) public virtual;

  function setTermEndTime(uint256 newTermEndTime) external virtual;

  function setNextDueTime(uint256 newNextDueTime) external virtual;

  function setInterestOwed(uint256 newInterestOwed) external virtual;

  function setPrincipalOwed(uint256 newPrincipalOwed) external virtual;

  function setInterestAccruedAsOf(uint256 newInterestAccruedAsOf) external virtual;

  function setWritedownAmount(uint256 newWritedownAmount) external virtual;

  function setLastFullPaymentTime(uint256 newLastFullPaymentTime) external virtual;

  function setLateFeeApr(uint256 newLateFeeApr) external virtual;

  function updateGoldfinchConfig() external virtual;
}

// File: alloyx-smart-contracts-v2/contracts/goldfinch/interfaces/ITranchedPool.sol


pragma solidity ^0.8.7;


abstract contract ITranchedPool {
  IV2CreditLine public creditLine;
  uint256 public createdAt;

  enum Tranches {
    Reserved,
    Senior,
    Junior
  }

  struct TrancheInfo {
    uint256 id;
    uint256 principalDeposited;
    uint256 principalSharePrice;
    uint256 interestSharePrice;
    uint256 lockedUntil;
  }

  struct PoolSlice {
    TrancheInfo seniorTranche;
    TrancheInfo juniorTranche;
    uint256 totalInterestAccrued;
    uint256 principalDeployed;
  }

  struct SliceInfo {
    uint256 reserveFeePercent;
    uint256 interestAccrued;
    uint256 principalAccrued;
  }

  struct ApplyResult {
    uint256 interestRemaining;
    uint256 principalRemaining;
    uint256 reserveDeduction;
    uint256 oldInterestSharePrice;
    uint256 oldPrincipalSharePrice;
  }

  function initialize(
    address _config,
    address _borrower,
    uint256 _juniorFeePercent,
    uint256 _limit,
    uint256 _interestApr,
    uint256 _paymentPeriodInDays,
    uint256 _termInDays,
    uint256 _lateFeeApr,
    uint256 _principalGracePeriodInDays,
    uint256 _fundableAt,
    uint256[] calldata _allowedUIDTypes
  ) public virtual;

  function getTranche(uint256 tranche) external view virtual returns (TrancheInfo memory);

  function pay(uint256 amount) external virtual;

  function lockJuniorCapital() external virtual;

  function lockPool() external virtual;

  function initializeNextSlice(uint256 _fundableAt) external virtual;

  function totalJuniorDeposits() external view virtual returns (uint256);

  function drawdown(uint256 amount) external virtual;

  function setFundableAt(uint256 timestamp) external virtual;

  function deposit(uint256 tranche, uint256 amount) external virtual returns (uint256 tokenId);

  function assess() external virtual;

  function depositWithPermit(
    uint256 tranche,
    uint256 amount,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external virtual returns (uint256 tokenId);

  function availableToWithdraw(uint256 tokenId)
    external
    view
    virtual
    returns (uint256 interestRedeemable, uint256 principalRedeemable);

  function withdraw(uint256 tokenId, uint256 amount)
    external
    virtual
    returns (uint256 interestWithdrawn, uint256 principalWithdrawn);

  function withdrawMax(uint256 tokenId)
    external
    virtual
    returns (uint256 interestWithdrawn, uint256 principalWithdrawn);

  function withdrawMultiple(uint256[] calldata tokenIds, uint256[] calldata amounts)
    external
    virtual;
}

// File: alloyx-smart-contracts-v2/contracts/goldfinch/interfaces/ISeniorPool.sol


pragma solidity ^0.8.7;


abstract contract ISeniorPool {
  uint256 public sharePrice;
  uint256 public totalLoansOutstanding;
  uint256 public totalWritedowns;

  function deposit(uint256 amount) external virtual returns (uint256 depositShares);

  function depositWithPermit(
    uint256 amount,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external virtual returns (uint256 depositShares);

  function withdraw(uint256 usdcAmount) external virtual returns (uint256 amount);

  function withdrawInFidu(uint256 fiduAmount) external virtual returns (uint256 amount);

  function sweepToCompound() public virtual;

  function sweepFromCompound() public virtual;

  function invest(ITranchedPool pool) public virtual;

  function estimateInvestment(ITranchedPool pool) public view virtual returns (uint256);

  function redeem(uint256 tokenId) public virtual;

  function writedown(uint256 tokenId) public virtual;

  function calculateWritedown(uint256 tokenId)
    public
    view
    virtual
    returns (uint256 writedownAmount);

  function assets() public view virtual returns (uint256);

  function getNumShares(uint256 amount) public view virtual returns (uint256);
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // 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 (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @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) {
        return a + b;
    }

    /**
     * @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 a - b;
    }

    /**
     * @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) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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 a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting 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) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC721Receiver} interface.
 *
 * Accepts all token transfers.
 * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
 */
contract ERC721Holder is IERC721Receiver {
    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     *
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

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

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: alloyx-smart-contracts-v2/contracts/goldfinch/interfaces/IPoolTokens.sol


pragma solidity ^0.8.7;



interface IPoolTokens is IERC721, IERC721Enumerable {
  event TokenMinted(
    address indexed owner,
    address indexed pool,
    uint256 indexed tokenId,
    uint256 amount,
    uint256 tranche
  );

  event TokenRedeemed(
    address indexed owner,
    address indexed pool,
    uint256 indexed tokenId,
    uint256 principalRedeemed,
    uint256 interestRedeemed,
    uint256 tranche
  );
  event TokenBurned(address indexed owner, address indexed pool, uint256 indexed tokenId);

  struct TokenInfo {
    address pool;
    uint256 tranche;
    uint256 principalAmount;
    uint256 principalRedeemed;
    uint256 interestRedeemed;
  }

  struct MintParams {
    uint256 principalAmount;
    uint256 tranche;
  }

  function mint(MintParams calldata params, address to) external returns (uint256);

  function redeem(
    uint256 tokenId,
    uint256 principalRedeemed,
    uint256 interestRedeemed
  ) external;

  function burn(uint256 tokenId) external;

  function onPoolCreated(address newPool) external;

  function getTokenInfo(uint256 tokenId) external view returns (TokenInfo memory);

  function validPool(address sender) external view returns (bool);

  function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: alloyx-smart-contracts-v2/contracts/alloyx/AlloyxTokenCRWN.sol


pragma solidity ^0.8.2;



contract AlloyxTokenCRWN is ERC20, Ownable {
  constructor() ERC20("Crown Gold", "CRWN") {}

  function mint(address _account, uint256 _amount) external onlyOwner returns (bool) {
    _mint(_account, _amount);
    return true;
  }

  function burn(address _account, uint256 _amount) external onlyOwner returns (bool) {
    _burn(_account, _amount);
    return true;
  }

  function contractName() external pure returns (string memory) {
    return "AlloyxTokenCRWN";
  }
}

// File: alloyx-smart-contracts-v2/contracts/alloyx/AlloyxTokenDURA.sol


pragma solidity ^0.8.2;



contract AlloyxTokenDURA is ERC20, Ownable {
  constructor() ERC20("Duralumin", "DURA") {}

  function mint(address _account, uint256 _amount) external onlyOwner returns (bool) {
    _mint(_account, _amount);
    return true;
  }

  function burn(address _account, uint256 _amount) external onlyOwner returns (bool) {
    _burn(_account, _amount);
    return true;
  }

  function contractName() external pure returns (string memory) {
    return "AlloyxTokenDura";
  }
}

// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;



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

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

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

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

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

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: alloyx-smart-contracts-v2/contracts/alloyx/IGoldfinchDelegacy.sol


pragma solidity ^0.8.7;









/**
 * @title Goldfinch Delegacy Interface
 * @notice Middle layer to communicate with goldfinch contracts
 * @author AlloyX
 */
interface IGoldfinchDelegacy {
  /**
   * @notice GoldFinch PoolToken Value in Value in term of USDC
   */
  function getGoldfinchDelegacyBalanceInUSDC() external view returns (uint256);

  /**
   * @notice Claim certain amount of reward token based on alloy silver token, the method will burn the silver token of
   * the amount of message sender, and transfer reward token to message sender
   * @param _rewardee the address of rewardee
   * @param _amount the amount of silver tokens used to claim
   * @param _totalSupply total claimable and claimed silver tokens of all stakeholders
   * @param _percentageFee the earning fee for redeeming silver token in percentage in terms of GFI
   */
  function claimReward(
    address _rewardee,
    uint256 _amount,
    uint256 _totalSupply,
    uint256 _percentageFee
  ) external;

  /**
   * @notice Get gfi amount that should be transfered to the claimer for the amount of CRWN
   * @param _amount the amount of silver tokens used to claim
   * @param _totalSupply total claimable and claimed silver tokens of all stakeholders
   * @param _percentageFee the earning fee for redeeming silver token in percentage in terms of GFI
   */
  function getRewardAmount(
    uint256 _amount,
    uint256 _totalSupply,
    uint256 _percentageFee
  ) external view returns (uint256);

  /**
   * @notice Purchase junior token through this delegacy to get pooltoken inside this delegacy
   * @param _amount the amount of usdc to purchase by
   * @param _poolAddress the pool address to buy from
   * @param _tranche the tranch id
   */
  function purchaseJuniorToken(
    uint256 _amount,
    address _poolAddress,
    uint256 _tranche
  ) external;

  /**
   * @notice Sell junior token through this delegacy to get repayments
   * @param _tokenId the ID of token to sell
   * @param _amount the amount to withdraw
   * @param _poolAddress the pool address to withdraw from
   * @param _percentageBronzeRepayment the repayment fee for bronze token in percentage
   */
  function sellJuniorToken(
    uint256 _tokenId,
    uint256 _amount,
    address _poolAddress,
    uint256 _percentageBronzeRepayment
  ) external;

  /**
   * @notice Purchase senior token through this delegacy to get FIDU inside this delegacy
   * @param _amount the amount of USDC to purchase by
   */
  function purchaseSeniorTokens(uint256 _amount) external;

  /**
   * @notice sell senior token through delegacy to redeem fidu
   * @param _amount the amount of fidu to sell
   * @param _percentageBronzeRepayment the repayment fee for bronze token in percentage
   */
  function sellSeniorTokens(uint256 _amount, uint256 _percentageBronzeRepayment) external;

  /**
   * @notice Validates the Pooltoken to be deposited and get the USDC value of the token
   * @param _tokenAddress the Pooltoken address
   * @param _depositor the person to deposit
   * @param _tokenID the ID of the Pooltoken
   */
  function validatesTokenToDepositAndGetPurchasePrice(
    address _tokenAddress,
    address _depositor,
    uint256 _tokenID
  ) external returns (uint256);

  /**
   * @notice Pay USDC tokens to account
   * @param _to the address to pay to
   * @param _amount the amount to pay
   */
  function payUsdc(address _to, uint256 _amount) external;

  /**
   * @notice Approve certain amount token of certain address to some other account
   * @param _account the address to approve
   * @param _amount the amount to approve
   * @param _tokenAddress the token address to approve
   */
  function approve(
    address _tokenAddress,
    address _account,
    uint256 _amount
  ) external;
}

// File: alloyx-smart-contracts-v2/contracts/alloyx/v4.0/AlloyxVaultV4.0.sol


pragma solidity ^0.8.7;












/**
 * @title AlloyX Vault
 * @notice Initial vault for AlloyX. This vault holds loan tokens generated on Goldfinch
 * and emits AlloyTokens when a liquidity provider deposits supported stable coins.
 * @author AlloyX
 */
contract AlloyxVaultV4_0 is ERC721Holder, Ownable, Pausable {
  using SafeERC20 for IERC20;
  using SafeERC20 for AlloyxTokenDURA;
  using SafeMath for uint256;
  struct StakeInfo {
    uint256 amount;
    uint256 since;
  }
  bool private vaultStarted;
  IERC20 private usdcCoin;
  AlloyxTokenDURA private alloyxTokenDURA;
  AlloyxTokenCRWN private alloyxTokenCRWN;
  IGoldfinchDelegacy private goldfinchDelegacy;
  address[] internal stakeholders;
  mapping(address => StakeInfo) private stakesMapping;
  mapping(address => uint256) private pastRedeemableReward;
  mapping(address => bool) whitelistedAddresses;
  uint256 public percentageRewardPerYear = 2;
  uint256 public percentageDURARedemption = 1;
  uint256 public percentageDURARepayment = 2;
  uint256 public percentageCRWNEarning = 10;
  uint256 public redemptionFee = 0;

  event DepositStable(address _tokenAddress, address _tokenSender, uint256 _tokenAmount);
  event DepositNFT(address _tokenAddress, address _tokenSender, uint256 _tokenID);
  event DepositAlloyx(address _tokenAddress, address _tokenSender, uint256 _tokenAmount);
  event PurchaseSenior(uint256 amount);
  event SellSenior(uint256 amount);
  event PurchaseJunior(uint256 amount);
  event SellJunior(uint256 amount);
  event Mint(address _tokenReceiver, uint256 _tokenAmount);
  event Burn(address _tokenReceiver, uint256 _tokenAmount);
  event Reward(address _tokenReceiver, uint256 _tokenAmount);
  event Claim(address _tokenReceiver, uint256 _tokenAmount);
  event Stake(address _staker, uint256 _amount);
  event Unstake(address _unstaker, uint256 _amount);

  constructor(
    address _alloyxDURAAddress,
    address _alloyxCRWNAddress,
    address _usdcCoinAddress,
    address _goldfinchDelegacy
  ) {
    alloyxTokenDURA = AlloyxTokenDURA(_alloyxDURAAddress);
    alloyxTokenCRWN = AlloyxTokenCRWN(_alloyxCRWNAddress);
    usdcCoin = IERC20(_usdcCoinAddress);
    goldfinchDelegacy = IGoldfinchDelegacy(_goldfinchDelegacy);
    vaultStarted = false;
  }

  /**
   * @notice If vault is started
   */
  modifier whenVaultStarted() {
    require(vaultStarted, "Vault has not start accepting deposits");
    _;
  }

  /**
   * @notice If vault is not started
   */
  modifier whenVaultNotStarted() {
    require(!vaultStarted, "Vault has already start accepting deposits");
    _;
  }

  /**
   * @notice If address is whitelisted
   * @param _address The address to verify.
   */
  modifier isWhitelisted(address _address) {
    require(whitelistedAddresses[_address], "You need to be whitelisted");
    _;
  }

  /**
   * @notice If address is not whitelisted
   * @param _address The address to verify.
   */
  modifier notWhitelisted(address _address) {
    require(!whitelistedAddresses[_address], "You are whitelisted");
    _;
  }

  /**
   * @notice Initialize by minting the alloy brown tokens to owner
   */
  function startVaultOperation() external onlyOwner whenVaultNotStarted returns (bool) {
    uint256 totalBalanceInUSDC = getAlloyxDURATokenBalanceInUSDC();
    require(totalBalanceInUSDC > 0, "Vault must have positive value before start");
    alloyxTokenDURA.mint(
      address(this),
      totalBalanceInUSDC.mul(alloyMantissa()).div(usdcMantissa())
    );
    vaultStarted = true;
    return true;
  }

  /**
   * @notice Pause all operations except migration of tokens
   */
  function pause() external onlyOwner whenNotPaused {
    _pause();
  }

  /**
   * @notice Unpause all operations
   */
  function unpause() external onlyOwner whenPaused {
    _unpause();
  }

  /**
   * @notice Add whitelist address
   * @param _addressToWhitelist The address to whitelist.
   */
  function addWhitelistedUser(address _addressToWhitelist)
    public
    onlyOwner
    notWhitelisted(_addressToWhitelist)
  {
    whitelistedAddresses[_addressToWhitelist] = true;
  }

  /**
   * @notice Remove whitelist address
   * @param _addressToDeWhitelist The address to de-whitelist.
   */
  function removeWhitelistedUser(address _addressToDeWhitelist)
    public
    onlyOwner
    isWhitelisted(_addressToDeWhitelist)
  {
    whitelistedAddresses[_addressToDeWhitelist] = false;
  }

  /**
   * @notice Check whether user is whitelisted
   * @param _whitelistedAddress The address to whitelist.
   */
  function isUserWhitelisted(address _whitelistedAddress) public view returns (bool) {
    return whitelistedAddresses[_whitelistedAddress];
  }

  /**
   * @notice Check if an address is a stakeholder.
   * @param _address The address to verify.
   * @return bool, uint256 Whether the address is a stakeholder,
   * and if so its position in the stakeholders array.
   */
  function isStakeholder(address _address) public view returns (bool, uint256) {
    for (uint256 s = 0; s < stakeholders.length; s += 1) {
      if (_address == stakeholders[s]) return (true, s);
    }
    return (false, 0);
  }

  /**
   * @notice Add a stakeholder.
   * @param _stakeholder The stakeholder to add.
   */
  function addStakeholder(address _stakeholder) internal {
    (bool _isStakeholder, ) = isStakeholder(_stakeholder);
    if (!_isStakeholder) stakeholders.push(_stakeholder);
  }

  /**
   * @notice Remove a stakeholder.
   * @param _stakeholder The stakeholder to remove.
   */
  function removeStakeholder(address _stakeholder) internal {
    (bool _isStakeholder, uint256 s) = isStakeholder(_stakeholder);
    if (_isStakeholder) {
      stakeholders[s] = stakeholders[stakeholders.length - 1];
      stakeholders.pop();
    }
  }

  /**
   * @notice Retrieve the stake for a stakeholder.
   * @param _stakeholder The stakeholder to retrieve the stake for.
   * @return Stake The amount staked and the time since when it's staked.
   */
  function stakeOf(address _stakeholder) public view returns (StakeInfo memory) {
    return stakesMapping[_stakeholder];
  }

  /**
   * @notice A method for a stakeholder to reset the timestamp of the stake.
   */
  function resetStakeTimestamp() internal {
    if (stakesMapping[msg.sender].amount == 0) addStakeholder(msg.sender);
    addPastRedeemableReward(msg.sender, stakesMapping[msg.sender]);
    stakesMapping[msg.sender] = StakeInfo(stakesMapping[msg.sender].amount, block.timestamp);
  }

  /**
   * @notice Add stake for a staker
   * @param _staker The person intending to stake
   * @param _stake The size of the stake to be created.
   */
  function addStake(address _staker, uint256 _stake) internal {
    if (stakesMapping[_staker].amount == 0) addStakeholder(_staker);
    addPastRedeemableReward(_staker, stakesMapping[_staker]);
    stakesMapping[_staker] = StakeInfo(stakesMapping[_staker].amount.add(_stake), block.timestamp);
  }

  /**
   * @notice Remove stake for a staker
   * @param _staker The person intending to remove stake
   * @param _stake The size of the stake to be removed.
   */
  function removeStake(address _staker, uint256 _stake) internal {
    require(stakeOf(_staker).amount >= _stake, "User has insufficient dura coin staked");
    if (stakesMapping[_staker].amount == 0) addStakeholder(_staker);
    addPastRedeemableReward(_staker, stakesMapping[_staker]);
    stakesMapping[_staker] = StakeInfo(stakesMapping[_staker].amount.sub(_stake), block.timestamp);
  }

  /**
   * @notice Add the stake to past redeemable reward
   * @param _stake the stake to be added into the reward
   */
  function addPastRedeemableReward(address _staker, StakeInfo storage _stake) internal {
    uint256 additionalPastRedeemableReward = calculateRewardFromStake(_stake);
    pastRedeemableReward[_staker] = pastRedeemableReward[_staker].add(
      additionalPastRedeemableReward
    );
  }

  /**
   * @notice Stake more into the vault, which will cause the user's DURA token to transfer to vault
   * @param _amount the amount the message sender intending to stake in
   */
  function stake(uint256 _amount) external whenNotPaused whenVaultStarted returns (bool) {
    addStake(msg.sender, _amount);
    alloyxTokenDURA.safeTransferFrom(msg.sender, address(this), _amount);
    emit Stake(msg.sender, _amount);
    return true;
  }

  /**
   * @notice Unstake some from the vault, which will cause the vault to transfer DURA token back to message sender
   * @param _amount the amount the message sender intending to unstake
   */
  function unstake(uint256 _amount) external whenNotPaused whenVaultStarted returns (bool) {
    removeStake(msg.sender, _amount);
    alloyxTokenDURA.safeTransfer(msg.sender, _amount);
    emit Unstake(msg.sender, _amount);
    return true;
  }

  /**
   * @notice A method for a stakeholder to clear a stake.
   */
  function clearStake() internal {
    resetStakeTimestamp();
  }

  /**
   * @notice A method for a stakeholder to clear a stake with some leftover reward
   * @param _reward the leftover reward the staker owns
   */
  function resetStakeTimestampWithRewardLeft(uint256 _reward) internal {
    resetStakeTimestamp();
    pastRedeemableReward[msg.sender] = _reward;
  }

  function calculateRewardFromStake(StakeInfo memory _stake) internal view returns (uint256) {
    return
      _stake
        .amount
        .mul(block.timestamp.sub(_stake.since))
        .mul(percentageRewardPerYear)
        .div(100)
        .div(365 days);
  }

  /**
   * @notice Claimable CRWN token amount of an address
   * @param _receiver the address of receiver
   */
  function claimableCRWNToken(address _receiver) public view returns (uint256) {
    StakeInfo memory stakeValue = stakeOf(_receiver);
    return pastRedeemableReward[_receiver] + calculateRewardFromStake(stakeValue);
  }

  /**
   * @notice Total claimable CRWN tokens of all stakeholders
   */
  function totalClaimableCRWNToken() public view returns (uint256) {
    uint256 total = 0;
    for (uint256 i = 0; i < stakeholders.length; i++) {
      total = total.add(claimableCRWNToken(stakeholders[i]));
    }
    return total;
  }

  /**
   * @notice Total claimable and claimed CRWN tokens of all stakeholders
   */
  function totalClaimableAndClaimedCRWNToken() public view returns (uint256) {
    return totalClaimableCRWNToken().add(alloyxTokenCRWN.totalSupply());
  }

  /**
   * @notice Claim all alloy CRWN tokens of the message sender, the method will mint the CRWN token of the claimable
   * amount to message sender, and clear the past rewards to zero
   */
  function claimAllAlloyxCRWN() external whenNotPaused whenVaultStarted returns (bool) {
    uint256 reward = claimableCRWNToken(msg.sender);
    alloyxTokenCRWN.mint(msg.sender, reward);
    resetStakeTimestampWithRewardLeft(0);
    emit Claim(msg.sender, reward);
    return true;
  }

  /**
   * @notice Claim certain amount of alloy CRWN tokens of the message sender, the method will mint the CRWN token of
   * the claimable amount to message sender, and clear the past rewards to the remainder
   * @param _amount the amount to claim
   */
  function claimAlloyxCRWN(uint256 _amount) external whenNotPaused whenVaultStarted returns (bool) {
    uint256 allReward = claimableCRWNToken(msg.sender);
    require(allReward >= _amount, "User has claimed more than he's entitled");
    alloyxTokenCRWN.mint(msg.sender, _amount);
    resetStakeTimestampWithRewardLeft(allReward.sub(_amount));
    emit Claim(msg.sender, _amount);
    return true;
  }

  /**
   * @notice Claim certain amount of reward token based on alloy CRWN token, the method will burn the CRWN token of
   * the amount of message sender, and transfer reward token to message sender
   * @param _amount the amount to claim
   */
  function claimReward(uint256 _amount) external whenNotPaused whenVaultStarted returns (bool) {
    require(
      alloyxTokenCRWN.balanceOf(address(msg.sender)) >= _amount,
      "Balance of crown coin must be larger than the amount to claim"
    );
    goldfinchDelegacy.claimReward(
      msg.sender,
      _amount,
      totalClaimableAndClaimedCRWNToken(),
      percentageCRWNEarning
    );
    alloyxTokenCRWN.burn(msg.sender, _amount);
    emit Reward(msg.sender, _amount);
    return true;
  }

  /**
   * @notice Get reward token count if the amount of CRWN tokens are claimed
   * @param _amount the amount to claim
   */
  function getRewardTokenCount(uint256 _amount) external view returns (uint256) {
    return
      goldfinchDelegacy.getRewardAmount(
        _amount,
        totalClaimableAndClaimedCRWNToken(),
        percentageCRWNEarning
      );
  }

  /**
   * @notice Request the delegacy to approve certain tokens on certain account for certain amount, it is most used for
   * buying the goldfinch tokens, they need to be able to transfer usdc to them
   * @param _tokenAddress the leftover reward the staker owns
   * @param _account the account the delegacy going to approve
   * @param _amount the amount the delegacy going to approve
   */
  function approveDelegacy(
    address _tokenAddress,
    address _account,
    uint256 _amount
  ) external onlyOwner {
    goldfinchDelegacy.approve(_tokenAddress, _account, _amount);
  }

  /**
   * @notice Alloy DURA Token Value in terms of USDC
   */
  function getAlloyxDURATokenBalanceInUSDC() public view returns (uint256) {
    uint256 totalValue = getUSDCBalance().add(
      goldfinchDelegacy.getGoldfinchDelegacyBalanceInUSDC()
    );
    require(
      totalValue > redemptionFee,
      "the value of vault is not larger than redemption fee, something went wrong"
    );
    return
      getUSDCBalance().add(goldfinchDelegacy.getGoldfinchDelegacyBalanceInUSDC()).sub(
        redemptionFee
      );
  }

  /**
   * @notice USDC Value in Vault
   */
  function getUSDCBalance() internal view returns (uint256) {
    return usdcCoin.balanceOf(address(this));
  }

  /**
   * @notice Convert Alloyx DURA to USDC amount
   * @param _amount the amount of DURA token to convert to usdc
   */
  function alloyxDURAToUSDC(uint256 _amount) public view returns (uint256) {
    uint256 alloyDURATotalSupply = alloyxTokenDURA.totalSupply();
    uint256 totalVaultAlloyxDURAValueInUSDC = getAlloyxDURATokenBalanceInUSDC();
    return _amount.mul(totalVaultAlloyxDURAValueInUSDC).div(alloyDURATotalSupply);
  }

  /**
   * @notice Convert USDC Amount to Alloyx DURA
   * @param _amount the amount of usdc to convert to DURA token
   */
  function usdcToAlloyxDURA(uint256 _amount) public view returns (uint256) {
    uint256 alloyDURATotalSupply = alloyxTokenDURA.totalSupply();
    uint256 totalVaultAlloyxDURAValueInUSDC = getAlloyxDURATokenBalanceInUSDC();
    return _amount.mul(alloyDURATotalSupply).div(totalVaultAlloyxDURAValueInUSDC);
  }

  /**
   * @notice Set percentageRewardPerYear which is the reward per year in percentage
   * @param _percentageRewardPerYear the reward per year in percentage
   */
  function setPercentageRewardPerYear(uint256 _percentageRewardPerYear) external onlyOwner {
    percentageRewardPerYear = _percentageRewardPerYear;
  }

  /**
   * @notice Set percentageDURARedemption which is the redemption fee for DURA token in percentage
   * @param _percentageDURARedemption the redemption fee for DURA token in percentage
   */
  function setPercentageDURARedemption(uint256 _percentageDURARedemption) external onlyOwner {
    percentageDURARedemption = _percentageDURARedemption;
  }

  /**
   * @notice Set percentageDURARepayment which is the repayment fee for DURA token in percentage
   * @param _percentageDURARepayment the repayment fee for DURA token in percentage
   */
  function setPercentageDURARepayment(uint256 _percentageDURARepayment) external onlyOwner {
    percentageDURARepayment = _percentageDURARepayment;
  }

  /**
   * @notice Set percentageCRWNEarning which is the earning fee for redeeming CRWN token in percentage in terms of gfi
   * @param _percentageCRWNEarning the earning fee for redeeming CRWN token in percentage in terms of gfi
   */
  function setPercentageCRWNEarning(uint256 _percentageCRWNEarning) external onlyOwner {
    percentageCRWNEarning = _percentageCRWNEarning;
  }

  /**
   * @notice Alloy token with 18 decimals
   */
  function alloyMantissa() internal pure returns (uint256) {
    return uint256(10)**uint256(18);
  }

  /**
   * @notice USDC mantissa with 6 decimals
   */
  function usdcMantissa() internal pure returns (uint256) {
    return uint256(10)**uint256(6);
  }

  /**
   * @notice Change DURA token address
   * @param _alloyxAddress the address to change to
   */
  function changeAlloyxDURAAddress(address _alloyxAddress) external onlyOwner {
    alloyxTokenDURA = AlloyxTokenDURA(_alloyxAddress);
  }

  function changeGoldfinchDelegacyAddress(address _goldfinchDelegacy) external onlyOwner {
    goldfinchDelegacy = IGoldfinchDelegacy(_goldfinchDelegacy);
  }

  /**
   * @notice An Alloy token holder can deposit their tokens and redeem them for USDC
   * @param _tokenAmount Number of Alloy Tokens
   */
  function depositAlloyxDURATokens(uint256 _tokenAmount)
    external
    whenNotPaused
    whenVaultStarted
    isWhitelisted(msg.sender)
    returns (bool)
  {
    require(
      alloyxTokenDURA.balanceOf(msg.sender) >= _tokenAmount,
      "User has insufficient alloyx coin."
    );
    require(
      alloyxTokenDURA.allowance(msg.sender, address(this)) >= _tokenAmount,
      "User has not approved the vault for sufficient alloyx coin"
    );
    uint256 amountToWithdraw = alloyxDURAToUSDC(_tokenAmount);
    uint256 withdrawalFee = amountToWithdraw.mul(percentageDURARedemption).div(100);
    require(amountToWithdraw > 0, "The amount of stable coin to get is not larger than 0");
    require(
      usdcCoin.balanceOf(address(this)) >= amountToWithdraw,
      "The vault does not have sufficient stable coin"
    );
    alloyxTokenDURA.burn(msg.sender, _tokenAmount);
    usdcCoin.safeTransfer(msg.sender, amountToWithdraw.sub(withdrawalFee));
    redemptionFee = redemptionFee.add(withdrawalFee);
    emit DepositAlloyx(address(alloyxTokenDURA), msg.sender, _tokenAmount);
    emit Burn(msg.sender, _tokenAmount);
    return true;
  }

  /**
   * @notice A Liquidity Provider can deposit supported stable coins for Alloy Tokens
   * @param _tokenAmount Number of stable coin
   */
  function depositUSDCCoin(uint256 _tokenAmount)
    external
    whenNotPaused
    whenVaultStarted
    isWhitelisted(msg.sender)
    returns (bool)
  {
    require(usdcCoin.balanceOf(msg.sender) >= _tokenAmount, "User has insufficient stable coin");
    require(
      usdcCoin.allowance(msg.sender, address(this)) >= _tokenAmount,
      "User has not approved the vault for sufficient stable coin"
    );
    uint256 amountToMint = usdcToAlloyxDURA(_tokenAmount);
    require(amountToMint > 0, "The amount of alloyx DURA coin to get is not larger than 0");
    usdcCoin.safeTransferFrom(msg.sender, address(goldfinchDelegacy), _tokenAmount);
    alloyxTokenDURA.mint(msg.sender, amountToMint);
    emit DepositStable(address(usdcCoin), msg.sender, amountToMint);
    emit Mint(msg.sender, amountToMint);
    return true;
  }

  /**
   * @notice A Liquidity Provider can deposit supported stable coins for Alloy Tokens
   * @param _tokenAmount Number of stable coin
   */
  function depositUSDCCoinWithStake(uint256 _tokenAmount)
    external
    whenNotPaused
    whenVaultStarted
    isWhitelisted(msg.sender)
    returns (bool)
  {
    require(usdcCoin.balanceOf(msg.sender) >= _tokenAmount, "User has insufficient stable coin");
    require(
      usdcCoin.allowance(msg.sender, address(this)) >= _tokenAmount,
      "User has not approved the vault for sufficient stable coin"
    );
    uint256 amountToMint = usdcToAlloyxDURA(_tokenAmount);
    require(amountToMint > 0, "The amount of alloyx DURA coin to get is not larger than 0");
    usdcCoin.safeTransferFrom(msg.sender, address(this), _tokenAmount);
    alloyxTokenDURA.mint(address(this), amountToMint);
    addStake(msg.sender, amountToMint);
    emit DepositStable(address(usdcCoin), msg.sender, amountToMint);
    emit Mint(address(this), amountToMint);
    return true;
  }

  /**
   * @notice A Junior token holder can deposit their NFT for stable coin
   * @param _tokenAddress NFT Address
   * @param _tokenID NFT ID
   */
  function depositNFTToken(address _tokenAddress, uint256 _tokenID)
    external
    whenNotPaused
    whenVaultStarted
    isWhitelisted(msg.sender)
    returns (bool)
  {
    uint256 purchasePrice = goldfinchDelegacy.validatesTokenToDepositAndGetPurchasePrice(
      _tokenAddress,
      msg.sender,
      _tokenID
    );
    IERC721(_tokenAddress).safeTransferFrom(msg.sender, address(goldfinchDelegacy), _tokenID);
    goldfinchDelegacy.payUsdc(msg.sender, purchasePrice);
    emit DepositNFT(_tokenAddress, msg.sender, _tokenID);
    return true;
  }

  /**
   * @notice Purchase junior token through delegacy to get pooltoken inside the delegacy
   * @param _amount the amount of usdc to purchase by
   * @param _poolAddress the pool address to buy from
   * @param _tranche the tranch id
   */
  function purchaseJuniorToken(
    uint256 _amount,
    address _poolAddress,
    uint256 _tranche
  ) external onlyOwner {
    require(_amount > 0, "Must deposit more than zero");
    goldfinchDelegacy.purchaseJuniorToken(_amount, _poolAddress, _tranche);
    emit PurchaseJunior(_amount);
  }

  /**
   * @notice Sell junior token through delegacy to get repayments
   * @param _tokenId the ID of token to sell
   * @param _amount the amount to withdraw
   * @param _poolAddress the pool address to withdraw from
   */
  function sellJuniorToken(
    uint256 _tokenId,
    uint256 _amount,
    address _poolAddress
  ) external onlyOwner {
    require(_amount > 0, "Must sell more than zero");
    goldfinchDelegacy.sellJuniorToken(_tokenId, _amount, _poolAddress, percentageDURARepayment);
    emit SellSenior(_amount);
  }

  /**
   * @notice Purchase senior token through delegacy to get fidu inside the delegacy
   * @param _amount the amount of usdc to purchase by
   */
  function purchaseSeniorTokens(uint256 _amount) external onlyOwner {
    require(_amount > 0, "Must deposit more than zero");
    goldfinchDelegacy.purchaseSeniorTokens(_amount);
    emit PurchaseSenior(_amount);
  }

  /**
   * @notice Sell senior token through delegacy to redeem fidu
   * @param _amount the amount of fidu to sell
   */
  function sellSeniorTokens(uint256 _amount) external onlyOwner {
    require(_amount > 0, "Must sell more than zero");
    goldfinchDelegacy.sellSeniorTokens(_amount, percentageDURARepayment);
    emit SellSenior(_amount);
  }

  /**
   * @notice Destroy the contract
   */
  function destroy() external onlyOwner whenPaused {
    require(usdcCoin.balanceOf(address(this)) == 0, "Balance of stable coin must be 0");

    address payable addr = payable(address(owner()));
    selfdestruct(addr);
  }

  /**
   * @notice Migrate certain ERC20 to an address
   * @param _tokenAddress the token address to migrate
   * @param _to the address to transfer tokens to
   */
  function migrateERC20(address _tokenAddress, address _to) external onlyOwner whenPaused {
    uint256 balance = IERC20(_tokenAddress).balanceOf(address(this));
    IERC20(_tokenAddress).safeTransfer(_to, balance);
  }

  /**
   * @notice Transfer redemption fee to some other address
   * @param _to the address to transfer to
   */
  function transferRedemptionFee(address _to) external onlyOwner whenNotPaused {
    usdcCoin.safeTransfer(_to, redemptionFee);
    redemptionFee = 0;
  }

  /**
   * @notice Transfer the ownership of alloy CRWN and DURA token contract to some other address
   * @param _to the address to transfer ownership to
   */
  function transferAlloyxOwnership(address _to) external onlyOwner whenPaused {
    alloyxTokenDURA.transferOwnership(_to);
    alloyxTokenCRWN.transferOwnership(_to);
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_alloyxDURAAddress","type":"address"},{"internalType":"address","name":"_alloyxCRWNAddress","type":"address"},{"internalType":"address","name":"_usdcCoinAddress","type":"address"},{"internalType":"address","name":"_goldfinchDelegacy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenSender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"DepositAlloyx","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenSender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"DepositNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_tokenSender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"DepositStable","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PurchaseJunior","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PurchaseSenior","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tokenReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"Reward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SellJunior","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SellSenior","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_unstaker","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"address","name":"_addressToWhitelist","type":"address"}],"name":"addWhitelistedUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"alloyxDURAToUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approveDelegacy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_alloyxAddress","type":"address"}],"name":"changeAlloyxDURAAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_goldfinchDelegacy","type":"address"}],"name":"changeGoldfinchDelegacyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllAlloyxCRWN","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimAlloyxCRWN","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimableCRWNToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"depositAlloyxDURATokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"depositNFTToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"depositUSDCCoin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"depositUSDCCoinWithStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAlloyxDURATokenBalanceInUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getRewardTokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isStakeholder","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistedAddress","type":"address"}],"name":"isUserWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"migrateERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageCRWNEarning","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageDURARedemption","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageDURARepayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageRewardPerYear","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_poolAddress","type":"address"},{"internalType":"uint256","name":"_tranche","type":"uint256"}],"name":"purchaseJuniorToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"purchaseSeniorTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redemptionFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addressToDeWhitelist","type":"address"}],"name":"removeWhitelistedUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_poolAddress","type":"address"}],"name":"sellJuniorToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sellSeniorTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percentageCRWNEarning","type":"uint256"}],"name":"setPercentageCRWNEarning","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percentageDURARedemption","type":"uint256"}],"name":"setPercentageDURARedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percentageDURARepayment","type":"uint256"}],"name":"setPercentageDURARepayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percentageRewardPerYear","type":"uint256"}],"name":"setPercentageRewardPerYear","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakeholder","type":"address"}],"name":"stakeOf","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"since","type":"uint256"}],"internalType":"struct AlloyxVaultV4_0.StakeInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startVaultOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalClaimableAndClaimedCRWNToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimableCRWNToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferAlloyxOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferRedemptionFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"usdcToAlloyxDURA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405260026009556001600a556002600b55600a600c556000600d553480156200002a57600080fd5b5060405162003e1c38038062003e1c8339810160408190526200004d9162000127565b6200005833620000ba565b60008054600280546001600160a01b03199081166001600160a01b0398891617909155600380548216968816969096179095556001805486169487169490941790935560048054909416919094161790915561ffff60a01b1916905562000184565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200012257600080fd5b919050565b600080600080608085870312156200013e57600080fd5b62000149856200010a565b935062000159602086016200010a565b925062000169604086016200010a565b915062000179606086016200010a565b905092959194509250565b613c8880620001946000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c80638456cb5911610182578063c8977e02116100e9578063e91f03e6116100a2578063ef037b901161007c578063ef037b90146105ed578063f1a341f714610617578063f2fde38b1461062a578063fb237eb21461063d57600080fd5b8063e91f03e6146105ca578063e93039cb146105d2578063ede7bf60146105da57600080fd5b8063c8977e0214610562578063cb80714b14610575578063ce3c39c114610588578063d8ec06081461059b578063d905e9b4146105ae578063dabb98aa146105c157600080fd5b8063a694fc3a1161013b578063a694fc3a146104f0578063ae169a5014610503578063b231e25d14610516578063b338ad1614610529578063b7b1b8e91461053c578063c070c2bd1461054f57600080fd5b80638456cb591461048c5780638d6f4d21146104945780638da5cb5b1461049c5780638f2da01d146104b75780639cdad708146104ca578063a45921ff146104dd57600080fd5b80633f4ba83a116102265780635ddd351d116101df5780635ddd351d1461044557806364cdc99e1461044e578063715018a614610456578063816c1acd1461045e578063826335191461047157806383197ef01461048457600080fd5b80633f4ba83a146103ce57806342623360146103d6578063458f58151461040457806351ba97241461040d57806353c98f5a146104205780635c975abb1461043357600080fd5b80631b61eb67116102785780631b61eb6714610366578063223ea9b0146103795780632456a11d146103825780632a88ec54146103955780632c579213146103a85780632e17de78146103bb57600080fd5b806307dd2ef2146102c05780630d518001146102dc5780630d7a3c6e146102f45780630eb9a00714610307578063150b7a021461031c57806319859a6d14610353575b600080fd5b6102c9600c5481565b6040519081526020015b60405180910390f35b6102e4610669565b60405190151581526020016102d3565b6102c9610302366004613751565b6107a2565b61031a61031536600461359f565b610855565b005b61033a61032a366004613629565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016102d3565b6102c9610361366004613751565b6108a1565b61031a610374366004613783565b610943565b6102c9600b5481565b61031a610390366004613751565b610a66565b61031a6103a336600461359f565b610a95565b61031a6103b6366004613751565b610b0e565b6102e46103c9366004613751565b610c23565b61031a610cda565b6103e96103e436600461359f565b610d37565b604080518251815260209283015192810192909252016102d3565b6102c9600d5481565b6102e461041b366004613751565b610d7e565b6102e461042e366004613751565b610f19565b600054600160a01b900460ff166102e4565b6102c9600a5481565b6102c9611231565b61031a611294565b6102c961046c36600461359f565b6112c8565b61031a61047f366004613751565b611309565b61031a611338565b61031a611462565b6102e46114be565b6000546040516001600160a01b0390911681526020016102d3565b61031a6104c5366004613751565b61167f565b61031a6104d8366004613751565b611786565b61031a6104eb3660046135ed565b6117b5565b6102e46104fe366004613751565b611849565b6102e4610511366004613751565b6118f0565b61031a61052436600461359f565b611b72565b6102e4610537366004613705565b611c22565b61031a61054a36600461359f565b611e3e565b61031a61055d36600461359f565b611ec4565b6102e4610570366004613751565b611f10565b61031a610583366004613751565b612405565b6102e4610596366004613751565b612434565b61031a6105a936600461359f565b61273d565b61031a6105bc3660046135ba565b612851565b6102c960095481565b6102c9612939565b6102c9612ab6565b6102c96105e8366004613751565b612b4e565b6106006105fb36600461359f565b612bf3565b6040805192151583526020830191909152016102d3565b61031a6106253660046137a8565b612c5e565b61031a61063836600461359f565b612d7a565b6102e461064b36600461359f565b6001600160a01b031660009081526008602052604090205460ff1690565b60008054600160a01b900460ff161561069d5760405162461bcd60e51b8152600401610694906138f4565b60405180910390fd5b600054600160a81b900460ff166106c65760405162461bcd60e51b815260040161069490613a28565b60006106d1336112c8565b6003546040516340c10f1960e01b81529192506001600160a01b0316906340c10f1990610704903390859060040161381d565b602060405180830381600087803b15801561071e57600080fd5b505af1158015610732573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610756919061372f565b506107616000612e15565b7f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4338260405161079292919061381d565b60405180910390a1600191505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107f357600080fd5b505afa158015610807573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082b919061376a565b90506000610837612939565b905061084d816108478685612e2f565b90612e3b565b949350505050565b6000546001600160a01b0316331461087f5760405162461bcd60e51b8152600401610694906139bc565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6004546000906001600160a01b031663a2a9ccea836108be612ab6565b600c546040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160206040518083038186803b15801561090557600080fd5b505afa158015610919573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093d919061376a565b92915050565b6000546001600160a01b0316331461096d5760405162461bcd60e51b8152600401610694906139bc565b600083116109bd5760405162461bcd60e51b815260206004820152601b60248201527f4d757374206465706f736974206d6f7265207468616e207a65726f00000000006044820152606401610694565b60048054604051631b61eb6760e01b81529182018590526001600160a01b038481166024840152604483018490521690631b61eb6790606401600060405180830381600087803b158015610a1057600080fd5b505af1158015610a24573d6000803e3d6000fd5b505050507f7a3794cf7d311106018524dfd41878138e4264f1bee18e53f1c180a1627fa2b883604051610a5991815260200190565b60405180910390a1505050565b6000546001600160a01b03163314610a905760405162461bcd60e51b8152600401610694906139bc565b600955565b6000546001600160a01b03163314610abf5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff1615610ae95760405162461bcd60e51b8152600401610694906138f4565b600d54600154610b06916001600160a01b03909116908390612e47565b506000600d55565b6000546001600160a01b03163314610b385760405162461bcd60e51b8152600401610694906139bc565b60008111610b835760405162461bcd60e51b81526020600482015260186024820152774d7573742073656c6c206d6f7265207468616e207a65726f60401b6044820152606401610694565b60048054600b5460405163f5a4162760e01b815292830184905260248301526001600160a01b03169063f5a4162790604401600060405180830381600087803b158015610bcf57600080fd5b505af1158015610be3573d6000803e3d6000fd5b505050507fc3085fd698c0021cf2ad330617df928819e049637665217c5e7757452f991d3181604051610c1891815260200190565b60405180910390a150565b60008054600160a01b900460ff1615610c4e5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610c775760405162461bcd60e51b815260040161069490613a28565b610c813383612e9d565b600254610c98906001600160a01b03163384612e47565b7f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd3383604051610cc992919061381d565b60405180910390a15060015b919050565b6000546001600160a01b03163314610d045760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff16610d2d5760405162461bcd60e51b815260040161069490613869565b610d35612fb0565b565b6040805180820190915260008082526020820152506001600160a01b0316600090815260066020908152604091829020825180840190935280548352600101549082015290565b60008054600160a01b900460ff1615610da95760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610dd25760405162461bcd60e51b815260040161069490613a28565b6000610ddd336112c8565b905082811015610e405760405162461bcd60e51b815260206004820152602860248201527f557365722068617320636c61696d6564206d6f7265207468616e206865277320604482015267195b9d1a5d1b195960c21b6064820152608401610694565b6003546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610e72903390879060040161381d565b602060405180830381600087803b158015610e8c57600080fd5b505af1158015610ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec4919061372f565b50610ed7610ed28285613026565b612e15565b7f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d43384604051610f0892919061381d565b60405180910390a150600192915050565b60008054600160a01b900460ff1615610f445760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610f6d5760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16610f9c5760405162461bcd60e51b8152600401610694906139f1565b6001546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b158015610fdf57600080fd5b505afa158015610ff3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611017919061376a565b10156110355760405162461bcd60e51b81526004016106949061397b565b600154604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561107e57600080fd5b505afa158015611092573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b6919061376a565b10156110d45760405162461bcd60e51b81526004016106949061391e565b60006110df846107a2565b9050600081116111015760405162461bcd60e51b815260040161069490613897565b600454600154611120916001600160a01b039182169133911687613032565b6002546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990611152903390859060040161381d565b602060405180830381600087803b15801561116c57600080fd5b505af1158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a4919061372f565b506001546040517fa4f358c78f73b2049a06e0436c6728292334862a6fc2114f2de13f9cff58491f916111e6916001600160a01b0390911690339085906137f9565b60405180910390a17f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885338260405161121f92919061381d565b60405180910390a15060019392505050565b600080805b60055481101561128e5761127a6112736005838154811061125957611259613c26565b6000918252602090912001546001600160a01b03166112c8565b8390613059565b91508061128681613bf5565b915050611236565b50919050565b6000546001600160a01b031633146112be5760405162461bcd60e51b8152600401610694906139bc565b610d356000613065565b6000806112d483610d37565b90506112df816130b5565b6001600160a01b0384166000908152600760205260409020546113029190613a6e565b9392505050565b6000546001600160a01b031633146113335760405162461bcd60e51b8152600401610694906139bc565b600b55565b6000546001600160a01b031633146113625760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff1661138b5760405162461bcd60e51b815260040161069490613869565b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156113ce57600080fd5b505afa1580156113e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611406919061376a565b156114535760405162461bcd60e51b815260206004820181905260248201527f42616c616e6365206f6620737461626c6520636f696e206d75737420626520306044820152606401610694565b6000546001600160a01b031680ff5b6000546001600160a01b0316331461148c5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff16156114b65760405162461bcd60e51b8152600401610694906138f4565b610d356130f2565b600080546001600160a01b031633146114e95760405162461bcd60e51b8152600401610694906139bc565b600054600160a81b900460ff16156115565760405162461bcd60e51b815260206004820152602a60248201527f5661756c742068617320616c726561647920737461727420616363657074696e60448201526967206465706f7369747360b01b6064820152608401610694565b6000611560612939565b9050600081116115c65760405162461bcd60e51b815260206004820152602b60248201527f5661756c74206d757374206861766520706f7369746976652076616c7565206260448201526a19599bdc99481cdd185c9d60aa1b6064820152608401610694565b6002546001600160a01b03166340c10f19306115f56115e3613157565b6108476115ee613165565b8790612e2f565b6040518363ffffffff1660e01b815260040161161292919061381d565b602060405180830381600087803b15801561162c57600080fd5b505af1158015611640573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611664919061372f565b50506000805460ff60a81b1916600160a81b17905550600190565b6000546001600160a01b031633146116a95760405162461bcd60e51b8152600401610694906139bc565b600081116116f95760405162461bcd60e51b815260206004820152601b60248201527f4d757374206465706f736974206d6f7265207468616e207a65726f00000000006044820152606401610694565b60048054604051638f2da01d60e01b81529182018390526001600160a01b031690638f2da01d90602401600060405180830381600087803b15801561173d57600080fd5b505af1158015611751573d6000803e3d6000fd5b505050507fd483110686f79d1f5932d32add1024998649ddca927700b75bea458b4cb7cde681604051610c1891815260200190565b6000546001600160a01b031633146117b05760405162461bcd60e51b8152600401610694906139bc565b600a55565b6000546001600160a01b031633146117df5760405162461bcd60e51b8152600401610694906139bc565b6004805460405163e1f21c6760e01b81526001600160a01b039091169163e1f21c679161181291879187918791016137f9565b600060405180830381600087803b15801561182c57600080fd5b505af1158015611840573d6000803e3d6000fd5b50505050505050565b60008054600160a01b900460ff16156118745760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff1661189d5760405162461bcd60e51b815260040161069490613a28565b6118a73383613173565b6002546118bf906001600160a01b0316333085613032565b7febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a3383604051610cc992919061381d565b60008054600160a01b900460ff161561191b5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff166119445760405162461bcd60e51b815260040161069490613a28565b6003546040516370a0823160e01b815233600482015283916001600160a01b0316906370a082319060240160206040518083038186803b15801561198757600080fd5b505afa15801561199b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119bf919061376a565b1015611a335760405162461bcd60e51b815260206004820152603d60248201527f42616c616e6365206f662063726f776e20636f696e206d757374206265206c6160448201527f72676572207468616e2074686520616d6f756e7420746f20636c61696d0000006064820152608401610694565b6004546001600160a01b031663d848b0583384611a4e612ab6565b600c546040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602484019290925260448301526064820152608401600060405180830381600087803b158015611aa457600080fd5b505af1158015611ab8573d6000803e3d6000fd5b5050600354604051632770a7eb60e21b81526001600160a01b039091169250639dc29fac9150611aee903390869060040161381d565b602060405180830381600087803b158015611b0857600080fd5b505af1158015611b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b40919061372f565b507f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc93383604051610cc992919061381d565b6000546001600160a01b03163314611b9c5760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116600090815260086020526040902054819060ff1615611bfd5760405162461bcd60e51b8152602060048201526013602482015272165bdd48185c99481dda1a5d195b1a5cdd1959606a1b6044820152606401610694565b506001600160a01b03166000908152600860205260409020805460ff19166001179055565b60008054600160a01b900460ff1615611c4d5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16611c765760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16611ca55760405162461bcd60e51b8152600401610694906139f1565b600480546040516373f4047360e11b81526000926001600160a01b039092169163e7e808e691611cdb91899133918a91016137f9565b602060405180830381600087803b158015611cf557600080fd5b505af1158015611d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2d919061376a565b60048054604051632142170760e11b81529293506001600160a01b03808916936342842e0e93611d6393339316918a91016137f9565b600060405180830381600087803b158015611d7d57600080fd5b505af1158015611d91573d6000803e3d6000fd5b50506004805460405163196b544360e01b81526001600160a01b03909116935063196b54439250611dc691339186910161381d565b600060405180830381600087803b158015611de057600080fd5b505af1158015611df4573d6000803e3d6000fd5b505050507fc7e8b1bdbecdc8a549557efb2a2ab715cff51630caead31610000019e61dfa4b853386604051611e2b939291906137f9565b60405180910390a1506001949350505050565b6000546001600160a01b03163314611e685760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116600090815260086020526040902054819060ff16611ea25760405162461bcd60e51b8152600401610694906139f1565b506001600160a01b03166000908152600860205260409020805460ff19169055565b6000546001600160a01b03163314611eee5760405162461bcd60e51b8152600401610694906139bc565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008054600160a01b900460ff1615611f3b5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16611f645760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16611f935760405162461bcd60e51b8152600401610694906139f1565b6002546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b158015611fd657600080fd5b505afa158015611fea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200e919061376a565b10156120675760405162461bcd60e51b815260206004820152602260248201527f557365722068617320696e73756666696369656e7420616c6c6f797820636f69604482015261371760f11b6064820152608401610694565b600254604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e8919061376a565b101561215c5760405162461bcd60e51b815260206004820152603a60248201527f5573657220686173206e6f7420617070726f76656420746865207661756c742060448201527f666f722073756666696369656e7420616c6c6f797820636f696e0000000000006064820152608401610694565b600061216784612b4e565b905060006121856064610847600a5485612e2f90919063ffffffff16565b9050600082116121f55760405162461bcd60e51b815260206004820152603560248201527f54686520616d6f756e74206f6620737461626c6520636f696e20746f206765746044820152740206973206e6f74206c6172676572207468616e203605c1b6064820152608401610694565b6001546040516370a0823160e01b815230600482015283916001600160a01b0316906370a082319060240160206040518083038186803b15801561223857600080fd5b505afa15801561224c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612270919061376a565b10156122d55760405162461bcd60e51b815260206004820152602e60248201527f546865207661756c7420646f6573206e6f74206861766520737566666963696560448201526d373a1039ba30b136329031b7b4b760911b6064820152608401610694565b600254604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90612307903390899060040161381d565b602060405180830381600087803b15801561232157600080fd5b505af1158015612335573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612359919061372f565b5061237b336123688484613026565b6001546001600160a01b03169190612e47565b600d546123889082613059565b600d556002546040517f53fee901a59b4d2e659e450f8db17fc345e158fe408d2b39faf66d1f8c4a54fe916123cc916001600160a01b0390911690339089906137f9565b60405180910390a17fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca53386604051611e2b92919061381d565b6000546001600160a01b0316331461242f5760405162461bcd60e51b8152600401610694906139bc565b600c55565b60008054600160a01b900460ff161561245f5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff166124885760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff166124b75760405162461bcd60e51b8152600401610694906139f1565b6001546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b1580156124fa57600080fd5b505afa15801561250e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612532919061376a565b10156125505760405162461bcd60e51b81526004016106949061397b565b600154604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561259957600080fd5b505afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d1919061376a565b10156125ef5760405162461bcd60e51b81526004016106949061391e565b60006125fa846107a2565b90506000811161261c5760405162461bcd60e51b815260040161069490613897565b600154612634906001600160a01b0316333087613032565b6002546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990612666903090859060040161381d565b602060405180830381600087803b15801561268057600080fd5b505af1158015612694573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b8919061372f565b506126c33382613173565b6001546040517fa4f358c78f73b2049a06e0436c6728292334862a6fc2114f2de13f9cff58491f91612704916001600160a01b0390911690339085906137f9565b60405180910390a17f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885308260405161121f92919061381d565b6000546001600160a01b031633146127675760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff166127905760405162461bcd60e51b815260040161069490613869565b60025460405163f2fde38b60e01b81526001600160a01b0383811660048301529091169063f2fde38b90602401600060405180830381600087803b1580156127d757600080fd5b505af11580156127eb573d6000803e3d6000fd5b505060035460405163f2fde38b60e01b81526001600160a01b038581166004830152909116925063f2fde38b9150602401600060405180830381600087803b15801561283657600080fd5b505af115801561284a573d6000803e3d6000fd5b5050505050565b6000546001600160a01b0316331461287b5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff166128a45760405162461bcd60e51b815260040161069490613869565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b1580156128e657600080fd5b505afa1580156128fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291e919061376a565b90506129346001600160a01b0384168383612e47565b505050565b6000806129d3600460009054906101000a90046001600160a01b03166001600160a01b031663531d7dec6040518163ffffffff1660e01b815260040160206040518083038186803b15801561298d57600080fd5b505afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c5919061376a565b6129cd6131ea565b90613059565b9050600d548111612a5f5760405162461bcd60e51b815260206004820152604a60248201527f7468652076616c7565206f66207661756c74206973206e6f74206c617267657260448201527f207468616e20726564656d7074696f6e206665652c20736f6d657468696e672060648201526977656e742077726f6e6760b01b608482015260a401610694565b600d5460048054604080516314c75f7b60e21b81529051612ab09493612aaa936001600160a01b03169263531d7dec9281830192602092829003018186803b15801561298d57600080fd5b90613026565b91505090565b6000612b49600360009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0957600080fd5b505afa158015612b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b41919061376a565b6129cd611231565b905090565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b9f57600080fd5b505afa158015612bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd7919061376a565b90506000612be3612939565b905061084d826108478684612e2f565b60008060005b600554811015612c525760058181548110612c1657612c16613c26565b6000918252602090912001546001600160a01b0385811691161415612c4057600194909350915050565b612c4b600182613a6e565b9050612bf9565b50600093849350915050565b6000546001600160a01b03163314612c885760405162461bcd60e51b8152600401610694906139bc565b60008211612cd35760405162461bcd60e51b81526020600482015260186024820152774d7573742073656c6c206d6f7265207468616e207a65726f60401b6044820152606401610694565b60048054600b546040516393af90a960e01b8152928301869052602483018590526001600160a01b038481166044850152606484019190915216906393af90a990608401600060405180830381600087803b158015612d3157600080fd5b505af1158015612d45573d6000803e3d6000fd5b505050507fc3085fd698c0021cf2ad330617df928819e049637665217c5e7757452f991d3182604051610a5991815260200190565b6000546001600160a01b03163314612da45760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116612e095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610694565b612e1281613065565b50565b612e1d613266565b33600090815260076020526040902055565b60006113028284613b93565b60006113028284613a86565b6129348363a9059cbb60e01b8484604051602401612e6692919061381d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526132d4565b80612ea783610d37565b511015612f055760405162461bcd60e51b815260206004820152602660248201527f557365722068617320696e73756666696369656e74206475726120636f696e206044820152651cdd185ad95960d21b6064820152608401610694565b6001600160a01b038216600090815260066020526040902054612f2b57612f2b826133a6565b6001600160a01b0382166000908152600660205260409020612f4e908390613409565b6040805180820182526001600160a01b0384166000908152600660205291909120548190612f7c9084613026565b8152426020918201526001600160a01b03909316600090815260068452604090208151815592015160019092019190915550565b600054600160a01b900460ff16612fd95760405162461bcd60e51b815260040161069490613869565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006113028284613bb2565b613053846323b872dd60e01b858585604051602401612e66939291906137f9565b50505050565b60006113028284613a6e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061093d6301e1338061084760646108476009546130ec6130e489602001514261302690919063ffffffff16565b895190612e2f565b90612e2f565b600054600160a01b900460ff161561311c5760405162461bcd60e51b8152600401610694906138f4565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586130093390565b6000612b496006600a613aeb565b6000612b496012600a613aeb565b6001600160a01b03821660009081526006602052604090205461319957613199826133a6565b6001600160a01b03821660009081526006602052604090206131bc908390613409565b6040805180820182526001600160a01b0384166000908152600660205291909120548190612f7c9084613059565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561322e57600080fd5b505afa158015613242573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b49919061376a565b3360009081526006602052604090205461328357613283336133a6565b33600081815260066020526040902061329c9190613409565b604080518082018252336000818152600660208181529482208054855242868601908152939092529093529051825551600190910155565b6000613329826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134749092919063ffffffff16565b8051909150156129345780806020019051810190613347919061372f565b6129345760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610694565b60006133b182612bf3565b5090508061340557600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0384161790555b5050565b60408051808201909152815481526001820154602082015260009061342d906130b5565b6001600160a01b0384166000908152600760205260409020549091506134539082613059565b6001600160a01b039093166000908152600760205260409020929092555050565b606061084d8484600085856001600160a01b0385163b6134d65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610694565b600080866001600160a01b031685876040516134f291906137dd565b60006040518083038185875af1925050503d806000811461352f576040519150601f19603f3d011682016040523d82523d6000602084013e613534565b606091505b509150915061354482828661354f565b979650505050505050565b6060831561355e575081611302565b82511561356e5782518084602001fd5b8160405162461bcd60e51b81526004016106949190613836565b80356001600160a01b0381168114610cd557600080fd5b6000602082840312156135b157600080fd5b61130282613588565b600080604083850312156135cd57600080fd5b6135d683613588565b91506135e460208401613588565b90509250929050565b60008060006060848603121561360257600080fd5b61360b84613588565b925061361960208501613588565b9150604084013590509250925092565b6000806000806080858703121561363f57600080fd5b61364885613588565b935061365660208601613588565b925060408501359150606085013567ffffffffffffffff8082111561367a57600080fd5b818701915087601f83011261368e57600080fd5b8135818111156136a0576136a0613c3c565b604051601f8201601f19908116603f011681019083821181831017156136c8576136c8613c3c565b816040528281528a60208487010111156136e157600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561371857600080fd5b61372183613588565b946020939093013593505050565b60006020828403121561374157600080fd5b8151801515811461130257600080fd5b60006020828403121561376357600080fd5b5035919050565b60006020828403121561377c57600080fd5b5051919050565b60008060006060848603121561379857600080fd5b8335925061361960208501613588565b6000806000606084860312156137bd57600080fd5b83359250602084013591506137d460408501613588565b90509250925092565b600082516137ef818460208701613bc9565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020815260008251806020840152613855816040850160208701613bc9565b601f01601f19169190910160400192915050565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252603a908201527f54686520616d6f756e74206f6620616c6c6f7978204455524120636f696e207460408201527f6f20676574206973206e6f74206c6172676572207468616e2030000000000000606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252603a908201527f5573657220686173206e6f7420617070726f76656420746865207661756c742060408201527f666f722073756666696369656e7420737461626c6520636f696e000000000000606082015260800190565b60208082526021908201527f557365722068617320696e73756666696369656e7420737461626c6520636f696040820152603760f91b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601a908201527f596f75206e65656420746f2062652077686974656c6973746564000000000000604082015260600190565b60208082526026908201527f5661756c7420686173206e6f7420737461727420616363657074696e67206465604082015265706f7369747360d01b606082015260800190565b60008219821115613a8157613a81613c10565b500190565b600082613aa357634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115613ae3578160001904821115613ac957613ac9613c10565b80851615613ad657918102915b93841c9390800290613aad565b509250929050565b60006113028383600082613b015750600161093d565b81613b0e5750600061093d565b8160018114613b245760028114613b2e57613b4a565b600191505061093d565b60ff841115613b3f57613b3f613c10565b50506001821b61093d565b5060208310610133831016604e8410600b8410161715613b6d575081810a61093d565b613b778383613aa8565b8060001904821115613b8b57613b8b613c10565b029392505050565b6000816000190483118215151615613bad57613bad613c10565b500290565b600082821015613bc457613bc4613c10565b500390565b60005b83811015613be4578181015183820152602001613bcc565b838111156130535750506000910152565b6000600019821415613c0957613c09613c10565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212201297941ff9e3ac8ecb02dfe993e62281a7358bf7853d004ad7cdd7465c339c8064736f6c63430008070033000000000000000000000000d737babfde172caab0e583c1f71ff8065d8e02e60000000000000000000000001e6b127734ec66a729b366ce8b7184eb18fa6e20000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c80638456cb5911610182578063c8977e02116100e9578063e91f03e6116100a2578063ef037b901161007c578063ef037b90146105ed578063f1a341f714610617578063f2fde38b1461062a578063fb237eb21461063d57600080fd5b8063e91f03e6146105ca578063e93039cb146105d2578063ede7bf60146105da57600080fd5b8063c8977e0214610562578063cb80714b14610575578063ce3c39c114610588578063d8ec06081461059b578063d905e9b4146105ae578063dabb98aa146105c157600080fd5b8063a694fc3a1161013b578063a694fc3a146104f0578063ae169a5014610503578063b231e25d14610516578063b338ad1614610529578063b7b1b8e91461053c578063c070c2bd1461054f57600080fd5b80638456cb591461048c5780638d6f4d21146104945780638da5cb5b1461049c5780638f2da01d146104b75780639cdad708146104ca578063a45921ff146104dd57600080fd5b80633f4ba83a116102265780635ddd351d116101df5780635ddd351d1461044557806364cdc99e1461044e578063715018a614610456578063816c1acd1461045e578063826335191461047157806383197ef01461048457600080fd5b80633f4ba83a146103ce57806342623360146103d6578063458f58151461040457806351ba97241461040d57806353c98f5a146104205780635c975abb1461043357600080fd5b80631b61eb67116102785780631b61eb6714610366578063223ea9b0146103795780632456a11d146103825780632a88ec54146103955780632c579213146103a85780632e17de78146103bb57600080fd5b806307dd2ef2146102c05780630d518001146102dc5780630d7a3c6e146102f45780630eb9a00714610307578063150b7a021461031c57806319859a6d14610353575b600080fd5b6102c9600c5481565b6040519081526020015b60405180910390f35b6102e4610669565b60405190151581526020016102d3565b6102c9610302366004613751565b6107a2565b61031a61031536600461359f565b610855565b005b61033a61032a366004613629565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016102d3565b6102c9610361366004613751565b6108a1565b61031a610374366004613783565b610943565b6102c9600b5481565b61031a610390366004613751565b610a66565b61031a6103a336600461359f565b610a95565b61031a6103b6366004613751565b610b0e565b6102e46103c9366004613751565b610c23565b61031a610cda565b6103e96103e436600461359f565b610d37565b604080518251815260209283015192810192909252016102d3565b6102c9600d5481565b6102e461041b366004613751565b610d7e565b6102e461042e366004613751565b610f19565b600054600160a01b900460ff166102e4565b6102c9600a5481565b6102c9611231565b61031a611294565b6102c961046c36600461359f565b6112c8565b61031a61047f366004613751565b611309565b61031a611338565b61031a611462565b6102e46114be565b6000546040516001600160a01b0390911681526020016102d3565b61031a6104c5366004613751565b61167f565b61031a6104d8366004613751565b611786565b61031a6104eb3660046135ed565b6117b5565b6102e46104fe366004613751565b611849565b6102e4610511366004613751565b6118f0565b61031a61052436600461359f565b611b72565b6102e4610537366004613705565b611c22565b61031a61054a36600461359f565b611e3e565b61031a61055d36600461359f565b611ec4565b6102e4610570366004613751565b611f10565b61031a610583366004613751565b612405565b6102e4610596366004613751565b612434565b61031a6105a936600461359f565b61273d565b61031a6105bc3660046135ba565b612851565b6102c960095481565b6102c9612939565b6102c9612ab6565b6102c96105e8366004613751565b612b4e565b6106006105fb36600461359f565b612bf3565b6040805192151583526020830191909152016102d3565b61031a6106253660046137a8565b612c5e565b61031a61063836600461359f565b612d7a565b6102e461064b36600461359f565b6001600160a01b031660009081526008602052604090205460ff1690565b60008054600160a01b900460ff161561069d5760405162461bcd60e51b8152600401610694906138f4565b60405180910390fd5b600054600160a81b900460ff166106c65760405162461bcd60e51b815260040161069490613a28565b60006106d1336112c8565b6003546040516340c10f1960e01b81529192506001600160a01b0316906340c10f1990610704903390859060040161381d565b602060405180830381600087803b15801561071e57600080fd5b505af1158015610732573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610756919061372f565b506107616000612e15565b7f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4338260405161079292919061381d565b60405180910390a1600191505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107f357600080fd5b505afa158015610807573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082b919061376a565b90506000610837612939565b905061084d816108478685612e2f565b90612e3b565b949350505050565b6000546001600160a01b0316331461087f5760405162461bcd60e51b8152600401610694906139bc565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6004546000906001600160a01b031663a2a9ccea836108be612ab6565b600c546040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160206040518083038186803b15801561090557600080fd5b505afa158015610919573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093d919061376a565b92915050565b6000546001600160a01b0316331461096d5760405162461bcd60e51b8152600401610694906139bc565b600083116109bd5760405162461bcd60e51b815260206004820152601b60248201527f4d757374206465706f736974206d6f7265207468616e207a65726f00000000006044820152606401610694565b60048054604051631b61eb6760e01b81529182018590526001600160a01b038481166024840152604483018490521690631b61eb6790606401600060405180830381600087803b158015610a1057600080fd5b505af1158015610a24573d6000803e3d6000fd5b505050507f7a3794cf7d311106018524dfd41878138e4264f1bee18e53f1c180a1627fa2b883604051610a5991815260200190565b60405180910390a1505050565b6000546001600160a01b03163314610a905760405162461bcd60e51b8152600401610694906139bc565b600955565b6000546001600160a01b03163314610abf5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff1615610ae95760405162461bcd60e51b8152600401610694906138f4565b600d54600154610b06916001600160a01b03909116908390612e47565b506000600d55565b6000546001600160a01b03163314610b385760405162461bcd60e51b8152600401610694906139bc565b60008111610b835760405162461bcd60e51b81526020600482015260186024820152774d7573742073656c6c206d6f7265207468616e207a65726f60401b6044820152606401610694565b60048054600b5460405163f5a4162760e01b815292830184905260248301526001600160a01b03169063f5a4162790604401600060405180830381600087803b158015610bcf57600080fd5b505af1158015610be3573d6000803e3d6000fd5b505050507fc3085fd698c0021cf2ad330617df928819e049637665217c5e7757452f991d3181604051610c1891815260200190565b60405180910390a150565b60008054600160a01b900460ff1615610c4e5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610c775760405162461bcd60e51b815260040161069490613a28565b610c813383612e9d565b600254610c98906001600160a01b03163384612e47565b7f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd3383604051610cc992919061381d565b60405180910390a15060015b919050565b6000546001600160a01b03163314610d045760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff16610d2d5760405162461bcd60e51b815260040161069490613869565b610d35612fb0565b565b6040805180820190915260008082526020820152506001600160a01b0316600090815260066020908152604091829020825180840190935280548352600101549082015290565b60008054600160a01b900460ff1615610da95760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610dd25760405162461bcd60e51b815260040161069490613a28565b6000610ddd336112c8565b905082811015610e405760405162461bcd60e51b815260206004820152602860248201527f557365722068617320636c61696d6564206d6f7265207468616e206865277320604482015267195b9d1a5d1b195960c21b6064820152608401610694565b6003546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610e72903390879060040161381d565b602060405180830381600087803b158015610e8c57600080fd5b505af1158015610ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec4919061372f565b50610ed7610ed28285613026565b612e15565b7f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d43384604051610f0892919061381d565b60405180910390a150600192915050565b60008054600160a01b900460ff1615610f445760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16610f6d5760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16610f9c5760405162461bcd60e51b8152600401610694906139f1565b6001546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b158015610fdf57600080fd5b505afa158015610ff3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611017919061376a565b10156110355760405162461bcd60e51b81526004016106949061397b565b600154604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561107e57600080fd5b505afa158015611092573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b6919061376a565b10156110d45760405162461bcd60e51b81526004016106949061391e565b60006110df846107a2565b9050600081116111015760405162461bcd60e51b815260040161069490613897565b600454600154611120916001600160a01b039182169133911687613032565b6002546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990611152903390859060040161381d565b602060405180830381600087803b15801561116c57600080fd5b505af1158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a4919061372f565b506001546040517fa4f358c78f73b2049a06e0436c6728292334862a6fc2114f2de13f9cff58491f916111e6916001600160a01b0390911690339085906137f9565b60405180910390a17f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885338260405161121f92919061381d565b60405180910390a15060019392505050565b600080805b60055481101561128e5761127a6112736005838154811061125957611259613c26565b6000918252602090912001546001600160a01b03166112c8565b8390613059565b91508061128681613bf5565b915050611236565b50919050565b6000546001600160a01b031633146112be5760405162461bcd60e51b8152600401610694906139bc565b610d356000613065565b6000806112d483610d37565b90506112df816130b5565b6001600160a01b0384166000908152600760205260409020546113029190613a6e565b9392505050565b6000546001600160a01b031633146113335760405162461bcd60e51b8152600401610694906139bc565b600b55565b6000546001600160a01b031633146113625760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff1661138b5760405162461bcd60e51b815260040161069490613869565b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156113ce57600080fd5b505afa1580156113e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611406919061376a565b156114535760405162461bcd60e51b815260206004820181905260248201527f42616c616e6365206f6620737461626c6520636f696e206d75737420626520306044820152606401610694565b6000546001600160a01b031680ff5b6000546001600160a01b0316331461148c5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff16156114b65760405162461bcd60e51b8152600401610694906138f4565b610d356130f2565b600080546001600160a01b031633146114e95760405162461bcd60e51b8152600401610694906139bc565b600054600160a81b900460ff16156115565760405162461bcd60e51b815260206004820152602a60248201527f5661756c742068617320616c726561647920737461727420616363657074696e60448201526967206465706f7369747360b01b6064820152608401610694565b6000611560612939565b9050600081116115c65760405162461bcd60e51b815260206004820152602b60248201527f5661756c74206d757374206861766520706f7369746976652076616c7565206260448201526a19599bdc99481cdd185c9d60aa1b6064820152608401610694565b6002546001600160a01b03166340c10f19306115f56115e3613157565b6108476115ee613165565b8790612e2f565b6040518363ffffffff1660e01b815260040161161292919061381d565b602060405180830381600087803b15801561162c57600080fd5b505af1158015611640573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611664919061372f565b50506000805460ff60a81b1916600160a81b17905550600190565b6000546001600160a01b031633146116a95760405162461bcd60e51b8152600401610694906139bc565b600081116116f95760405162461bcd60e51b815260206004820152601b60248201527f4d757374206465706f736974206d6f7265207468616e207a65726f00000000006044820152606401610694565b60048054604051638f2da01d60e01b81529182018390526001600160a01b031690638f2da01d90602401600060405180830381600087803b15801561173d57600080fd5b505af1158015611751573d6000803e3d6000fd5b505050507fd483110686f79d1f5932d32add1024998649ddca927700b75bea458b4cb7cde681604051610c1891815260200190565b6000546001600160a01b031633146117b05760405162461bcd60e51b8152600401610694906139bc565b600a55565b6000546001600160a01b031633146117df5760405162461bcd60e51b8152600401610694906139bc565b6004805460405163e1f21c6760e01b81526001600160a01b039091169163e1f21c679161181291879187918791016137f9565b600060405180830381600087803b15801561182c57600080fd5b505af1158015611840573d6000803e3d6000fd5b50505050505050565b60008054600160a01b900460ff16156118745760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff1661189d5760405162461bcd60e51b815260040161069490613a28565b6118a73383613173565b6002546118bf906001600160a01b0316333085613032565b7febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a3383604051610cc992919061381d565b60008054600160a01b900460ff161561191b5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff166119445760405162461bcd60e51b815260040161069490613a28565b6003546040516370a0823160e01b815233600482015283916001600160a01b0316906370a082319060240160206040518083038186803b15801561198757600080fd5b505afa15801561199b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119bf919061376a565b1015611a335760405162461bcd60e51b815260206004820152603d60248201527f42616c616e6365206f662063726f776e20636f696e206d757374206265206c6160448201527f72676572207468616e2074686520616d6f756e7420746f20636c61696d0000006064820152608401610694565b6004546001600160a01b031663d848b0583384611a4e612ab6565b600c546040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602484019290925260448301526064820152608401600060405180830381600087803b158015611aa457600080fd5b505af1158015611ab8573d6000803e3d6000fd5b5050600354604051632770a7eb60e21b81526001600160a01b039091169250639dc29fac9150611aee903390869060040161381d565b602060405180830381600087803b158015611b0857600080fd5b505af1158015611b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b40919061372f565b507f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc93383604051610cc992919061381d565b6000546001600160a01b03163314611b9c5760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116600090815260086020526040902054819060ff1615611bfd5760405162461bcd60e51b8152602060048201526013602482015272165bdd48185c99481dda1a5d195b1a5cdd1959606a1b6044820152606401610694565b506001600160a01b03166000908152600860205260409020805460ff19166001179055565b60008054600160a01b900460ff1615611c4d5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16611c765760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16611ca55760405162461bcd60e51b8152600401610694906139f1565b600480546040516373f4047360e11b81526000926001600160a01b039092169163e7e808e691611cdb91899133918a91016137f9565b602060405180830381600087803b158015611cf557600080fd5b505af1158015611d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2d919061376a565b60048054604051632142170760e11b81529293506001600160a01b03808916936342842e0e93611d6393339316918a91016137f9565b600060405180830381600087803b158015611d7d57600080fd5b505af1158015611d91573d6000803e3d6000fd5b50506004805460405163196b544360e01b81526001600160a01b03909116935063196b54439250611dc691339186910161381d565b600060405180830381600087803b158015611de057600080fd5b505af1158015611df4573d6000803e3d6000fd5b505050507fc7e8b1bdbecdc8a549557efb2a2ab715cff51630caead31610000019e61dfa4b853386604051611e2b939291906137f9565b60405180910390a1506001949350505050565b6000546001600160a01b03163314611e685760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116600090815260086020526040902054819060ff16611ea25760405162461bcd60e51b8152600401610694906139f1565b506001600160a01b03166000908152600860205260409020805460ff19169055565b6000546001600160a01b03163314611eee5760405162461bcd60e51b8152600401610694906139bc565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008054600160a01b900460ff1615611f3b5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff16611f645760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff16611f935760405162461bcd60e51b8152600401610694906139f1565b6002546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b158015611fd657600080fd5b505afa158015611fea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200e919061376a565b10156120675760405162461bcd60e51b815260206004820152602260248201527f557365722068617320696e73756666696369656e7420616c6c6f797820636f69604482015261371760f11b6064820152608401610694565b600254604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e8919061376a565b101561215c5760405162461bcd60e51b815260206004820152603a60248201527f5573657220686173206e6f7420617070726f76656420746865207661756c742060448201527f666f722073756666696369656e7420616c6c6f797820636f696e0000000000006064820152608401610694565b600061216784612b4e565b905060006121856064610847600a5485612e2f90919063ffffffff16565b9050600082116121f55760405162461bcd60e51b815260206004820152603560248201527f54686520616d6f756e74206f6620737461626c6520636f696e20746f206765746044820152740206973206e6f74206c6172676572207468616e203605c1b6064820152608401610694565b6001546040516370a0823160e01b815230600482015283916001600160a01b0316906370a082319060240160206040518083038186803b15801561223857600080fd5b505afa15801561224c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612270919061376a565b10156122d55760405162461bcd60e51b815260206004820152602e60248201527f546865207661756c7420646f6573206e6f74206861766520737566666963696560448201526d373a1039ba30b136329031b7b4b760911b6064820152608401610694565b600254604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90612307903390899060040161381d565b602060405180830381600087803b15801561232157600080fd5b505af1158015612335573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612359919061372f565b5061237b336123688484613026565b6001546001600160a01b03169190612e47565b600d546123889082613059565b600d556002546040517f53fee901a59b4d2e659e450f8db17fc345e158fe408d2b39faf66d1f8c4a54fe916123cc916001600160a01b0390911690339089906137f9565b60405180910390a17fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca53386604051611e2b92919061381d565b6000546001600160a01b0316331461242f5760405162461bcd60e51b8152600401610694906139bc565b600c55565b60008054600160a01b900460ff161561245f5760405162461bcd60e51b8152600401610694906138f4565b600054600160a81b900460ff166124885760405162461bcd60e51b815260040161069490613a28565b3360008181526008602052604090205460ff166124b75760405162461bcd60e51b8152600401610694906139f1565b6001546040516370a0823160e01b815233600482015284916001600160a01b0316906370a082319060240160206040518083038186803b1580156124fa57600080fd5b505afa15801561250e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612532919061376a565b10156125505760405162461bcd60e51b81526004016106949061397b565b600154604051636eb1769f60e11b815233600482015230602482015284916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561259957600080fd5b505afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d1919061376a565b10156125ef5760405162461bcd60e51b81526004016106949061391e565b60006125fa846107a2565b90506000811161261c5760405162461bcd60e51b815260040161069490613897565b600154612634906001600160a01b0316333087613032565b6002546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990612666903090859060040161381d565b602060405180830381600087803b15801561268057600080fd5b505af1158015612694573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b8919061372f565b506126c33382613173565b6001546040517fa4f358c78f73b2049a06e0436c6728292334862a6fc2114f2de13f9cff58491f91612704916001600160a01b0390911690339085906137f9565b60405180910390a17f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885308260405161121f92919061381d565b6000546001600160a01b031633146127675760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff166127905760405162461bcd60e51b815260040161069490613869565b60025460405163f2fde38b60e01b81526001600160a01b0383811660048301529091169063f2fde38b90602401600060405180830381600087803b1580156127d757600080fd5b505af11580156127eb573d6000803e3d6000fd5b505060035460405163f2fde38b60e01b81526001600160a01b038581166004830152909116925063f2fde38b9150602401600060405180830381600087803b15801561283657600080fd5b505af115801561284a573d6000803e3d6000fd5b5050505050565b6000546001600160a01b0316331461287b5760405162461bcd60e51b8152600401610694906139bc565b600054600160a01b900460ff166128a45760405162461bcd60e51b815260040161069490613869565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b1580156128e657600080fd5b505afa1580156128fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291e919061376a565b90506129346001600160a01b0384168383612e47565b505050565b6000806129d3600460009054906101000a90046001600160a01b03166001600160a01b031663531d7dec6040518163ffffffff1660e01b815260040160206040518083038186803b15801561298d57600080fd5b505afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c5919061376a565b6129cd6131ea565b90613059565b9050600d548111612a5f5760405162461bcd60e51b815260206004820152604a60248201527f7468652076616c7565206f66207661756c74206973206e6f74206c617267657260448201527f207468616e20726564656d7074696f6e206665652c20736f6d657468696e672060648201526977656e742077726f6e6760b01b608482015260a401610694565b600d5460048054604080516314c75f7b60e21b81529051612ab09493612aaa936001600160a01b03169263531d7dec9281830192602092829003018186803b15801561298d57600080fd5b90613026565b91505090565b6000612b49600360009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0957600080fd5b505afa158015612b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b41919061376a565b6129cd611231565b905090565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b9f57600080fd5b505afa158015612bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd7919061376a565b90506000612be3612939565b905061084d826108478684612e2f565b60008060005b600554811015612c525760058181548110612c1657612c16613c26565b6000918252602090912001546001600160a01b0385811691161415612c4057600194909350915050565b612c4b600182613a6e565b9050612bf9565b50600093849350915050565b6000546001600160a01b03163314612c885760405162461bcd60e51b8152600401610694906139bc565b60008211612cd35760405162461bcd60e51b81526020600482015260186024820152774d7573742073656c6c206d6f7265207468616e207a65726f60401b6044820152606401610694565b60048054600b546040516393af90a960e01b8152928301869052602483018590526001600160a01b038481166044850152606484019190915216906393af90a990608401600060405180830381600087803b158015612d3157600080fd5b505af1158015612d45573d6000803e3d6000fd5b505050507fc3085fd698c0021cf2ad330617df928819e049637665217c5e7757452f991d3182604051610a5991815260200190565b6000546001600160a01b03163314612da45760405162461bcd60e51b8152600401610694906139bc565b6001600160a01b038116612e095760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610694565b612e1281613065565b50565b612e1d613266565b33600090815260076020526040902055565b60006113028284613b93565b60006113028284613a86565b6129348363a9059cbb60e01b8484604051602401612e6692919061381d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526132d4565b80612ea783610d37565b511015612f055760405162461bcd60e51b815260206004820152602660248201527f557365722068617320696e73756666696369656e74206475726120636f696e206044820152651cdd185ad95960d21b6064820152608401610694565b6001600160a01b038216600090815260066020526040902054612f2b57612f2b826133a6565b6001600160a01b0382166000908152600660205260409020612f4e908390613409565b6040805180820182526001600160a01b0384166000908152600660205291909120548190612f7c9084613026565b8152426020918201526001600160a01b03909316600090815260068452604090208151815592015160019092019190915550565b600054600160a01b900460ff16612fd95760405162461bcd60e51b815260040161069490613869565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006113028284613bb2565b613053846323b872dd60e01b858585604051602401612e66939291906137f9565b50505050565b60006113028284613a6e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061093d6301e1338061084760646108476009546130ec6130e489602001514261302690919063ffffffff16565b895190612e2f565b90612e2f565b600054600160a01b900460ff161561311c5760405162461bcd60e51b8152600401610694906138f4565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586130093390565b6000612b496006600a613aeb565b6000612b496012600a613aeb565b6001600160a01b03821660009081526006602052604090205461319957613199826133a6565b6001600160a01b03821660009081526006602052604090206131bc908390613409565b6040805180820182526001600160a01b0384166000908152600660205291909120548190612f7c9084613059565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561322e57600080fd5b505afa158015613242573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b49919061376a565b3360009081526006602052604090205461328357613283336133a6565b33600081815260066020526040902061329c9190613409565b604080518082018252336000818152600660208181529482208054855242868601908152939092529093529051825551600190910155565b6000613329826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134749092919063ffffffff16565b8051909150156129345780806020019051810190613347919061372f565b6129345760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610694565b60006133b182612bf3565b5090508061340557600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0384161790555b5050565b60408051808201909152815481526001820154602082015260009061342d906130b5565b6001600160a01b0384166000908152600760205260409020549091506134539082613059565b6001600160a01b039093166000908152600760205260409020929092555050565b606061084d8484600085856001600160a01b0385163b6134d65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610694565b600080866001600160a01b031685876040516134f291906137dd565b60006040518083038185875af1925050503d806000811461352f576040519150601f19603f3d011682016040523d82523d6000602084013e613534565b606091505b509150915061354482828661354f565b979650505050505050565b6060831561355e575081611302565b82511561356e5782518084602001fd5b8160405162461bcd60e51b81526004016106949190613836565b80356001600160a01b0381168114610cd557600080fd5b6000602082840312156135b157600080fd5b61130282613588565b600080604083850312156135cd57600080fd5b6135d683613588565b91506135e460208401613588565b90509250929050565b60008060006060848603121561360257600080fd5b61360b84613588565b925061361960208501613588565b9150604084013590509250925092565b6000806000806080858703121561363f57600080fd5b61364885613588565b935061365660208601613588565b925060408501359150606085013567ffffffffffffffff8082111561367a57600080fd5b818701915087601f83011261368e57600080fd5b8135818111156136a0576136a0613c3c565b604051601f8201601f19908116603f011681019083821181831017156136c8576136c8613c3c565b816040528281528a60208487010111156136e157600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561371857600080fd5b61372183613588565b946020939093013593505050565b60006020828403121561374157600080fd5b8151801515811461130257600080fd5b60006020828403121561376357600080fd5b5035919050565b60006020828403121561377c57600080fd5b5051919050565b60008060006060848603121561379857600080fd5b8335925061361960208501613588565b6000806000606084860312156137bd57600080fd5b83359250602084013591506137d460408501613588565b90509250925092565b600082516137ef818460208701613bc9565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020815260008251806020840152613855816040850160208701613bc9565b601f01601f19169190910160400192915050565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252603a908201527f54686520616d6f756e74206f6620616c6c6f7978204455524120636f696e207460408201527f6f20676574206973206e6f74206c6172676572207468616e2030000000000000606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252603a908201527f5573657220686173206e6f7420617070726f76656420746865207661756c742060408201527f666f722073756666696369656e7420737461626c6520636f696e000000000000606082015260800190565b60208082526021908201527f557365722068617320696e73756666696369656e7420737461626c6520636f696040820152603760f91b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601a908201527f596f75206e65656420746f2062652077686974656c6973746564000000000000604082015260600190565b60208082526026908201527f5661756c7420686173206e6f7420737461727420616363657074696e67206465604082015265706f7369747360d01b606082015260800190565b60008219821115613a8157613a81613c10565b500190565b600082613aa357634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115613ae3578160001904821115613ac957613ac9613c10565b80851615613ad657918102915b93841c9390800290613aad565b509250929050565b60006113028383600082613b015750600161093d565b81613b0e5750600061093d565b8160018114613b245760028114613b2e57613b4a565b600191505061093d565b60ff841115613b3f57613b3f613c10565b50506001821b61093d565b5060208310610133831016604e8410600b8410161715613b6d575081810a61093d565b613b778383613aa8565b8060001904821115613b8b57613b8b613c10565b029392505050565b6000816000190483118215151615613bad57613bad613c10565b500290565b600082821015613bc457613bc4613c10565b500390565b60005b83811015613be4578181015183820152602001613bcc565b838111156130535750506000910152565b6000600019821415613c0957613c09613c10565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212201297941ff9e3ac8ecb02dfe993e62281a7358bf7853d004ad7cdd7465c339c8064736f6c63430008070033

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

000000000000000000000000d737babfde172caab0e583c1f71ff8065d8e02e60000000000000000000000001e6b127734ec66a729b366ce8b7184eb18fa6e20000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48

-----Decoded View---------------
Arg [0] : _alloyxDURAAddress (address): 0xd737baBfde172CAab0E583C1f71FF8065d8e02e6
Arg [1] : _alloyxCRWNAddress (address): 0x1E6b127734EC66A729b366cE8B7184EB18FA6e20
Arg [2] : _usdcCoinAddress (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : _goldfinchDelegacy (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d737babfde172caab0e583c1f71ff8065d8e02e6
Arg [1] : 0000000000000000000000001e6b127734ec66a729b366ce8b7184eb18fa6e20
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48


Deployed Bytecode Sourcemap

66008:24357:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66783:41;;;;;;;;;17365:25:1;;;17353:2;17338:18;66783:41:0;;;;;;;;76612:290;;;:::i;:::-;;;5735:14:1;;5728:22;5710:41;;5698:2;5683:18;76612:290:0;5570:187:1;80627:312:0;;;;;;:::i;:::-;;:::i;82961:158::-;;;;;;:::i;:::-;;:::i;:::-;;17188:207;;;;;;:::i;:::-;-1:-1:-1;;;17188:207:0;;;;;;;;;;-1:-1:-1;;;;;;6187:33:1;;;6169:52;;6157:2;6142:18;17188:207:0;6025:202:1;78491:243:0;;;;;;:::i;:::-;;:::i;87472:301::-;;;;;;:::i;:::-;;:::i;66736:42::-;;;;;;81116:152;;;;;;:::i;:::-;;:::i;89864:155::-;;;;;;:::i;:::-;;:::i;88832:229::-;;;;;;:::i;:::-;;:::i;74507:248::-;;;;;;:::i;:::-;;:::i;69576:72::-;;;:::i;71881:125::-;;;;;;:::i;:::-;;:::i;:::-;;;;17131:13:1;;17113:32;;17201:4;17189:17;;;17183:24;17161:20;;;17154:54;;;;17086:18;71881:125:0;16913:301:1;66829:32:0;;;;;;77171:408;;;;;;:::i;:::-;;:::i;84599:844::-;;;;;;:::i;:::-;;:::i;19427:86::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;19427:86;;66688:43;;;;;;75917:241;;;:::i;22326:103::-;;;:::i;75613:222::-;;;;;;:::i;:::-;;:::i;81834:152::-;;;;;;:::i;:::-;;:::i;89116:227::-;;;:::i;69448:71::-;;;:::i;68953:413::-;;;:::i;21675:87::-;21721:7;21748:6;21675:87;;-1:-1:-1;;;;;21748:6:0;;;4118:51:1;;4106:2;4091:18;21675:87:0;3972:203:1;88481:219:0;;;;;;:::i;:::-;;:::i;81475:156::-;;;;;;:::i;:::-;;:::i;79144:194::-;;;;;;:::i;:::-;;:::i;74039:260::-;;;;;;:::i;:::-;;:::i;77837:515::-;;;;;;:::i;:::-;;:::i;69763:189::-;;;;;;:::i;:::-;;:::i;86647:569::-;;;;;;:::i;:::-;;:::i;70075:198::-;;;;;;:::i;:::-;;:::i;82817:138::-;;;;;;:::i;:::-;;:::i;83274:1170::-;;;;;;:::i;:::-;;:::i;82233:144::-;;;;;;:::i;:::-;;:::i;85598:887::-;;;;;;:::i;:::-;;:::i;90190:172::-;;;;;;:::i;:::-;;:::i;89520:220::-;;;;;;:::i;:::-;;:::i;66641:42::-;;;;;;79412:470;;;:::i;76252:155::-;;;:::i;80181:312::-;;;;;;:::i;:::-;;:::i;70783:232::-;;;;;;:::i;:::-;;:::i;:::-;;;;5955:14:1;;5948:22;5930:41;;6002:2;5987:18;;5980:34;;;;5903:18;70783:232:0;5762:258:1;88010:311:0;;;;;;:::i;:::-;;:::i;22584:201::-;;;;;;:::i;:::-;;:::i;70400:144::-;;;;;;:::i;:::-;-1:-1:-1;;;;;70497:41:0;70477:4;70497:41;;;:20;:41;;;;;;;;;70400:144;76612:290;76691:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;;;;;;;;;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;76704:14:::2;76721:30;76740:10;76721:18;:30::i;:::-;76758:15;::::0;:40:::2;::::0;-1:-1:-1;;;76758:40:0;;76704:47;;-1:-1:-1;;;;;;76758:15:0::2;::::0;:20:::2;::::0;:40:::2;::::0;76779:10:::2;::::0;76704:47;;76758:40:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;76805:36;76839:1;76805:33;:36::i;:::-;76853:25;76859:10;76871:6;76853:25;;;;;;;:::i;:::-;;;;;;;;76892:4;76885:11;;;76612:290:::0;:::o;80627:312::-;80691:7;80707:28;80738:15;;;;;;;;;-1:-1:-1;;;;;80738:15:0;-1:-1:-1;;;;;80738:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80707:60;;80774:39;80816:33;:31;:33::i;:::-;80774:75;-1:-1:-1;80863:70:0;80774:75;80863:33;:7;80875:20;80863:11;:33::i;:::-;:37;;:70::i;:::-;80856:77;80627:312;-1:-1:-1;;;;80627:312:0:o;82961:158::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;83055:17:::1;:58:::0;;-1:-1:-1;;;;;;83055:58:0::1;-1:-1:-1::0;;;;;83055:58:0;;;::::1;::::0;;;::::1;::::0;;82961:158::o;78491:243::-;78590:17;;78560:7;;-1:-1:-1;;;;;78590:17:0;:33;78634:7;78652:35;:33;:35::i;:::-;78698:21;;78590:138;;-1:-1:-1;;;;;;78590:138:0;;;;;;;;;;18628:25:1;;;;18669:18;;;18662:34;;;;18712:18;;;18705:34;18601:18;;78590:138:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78576:152;78491:243;-1:-1:-1;;78491:243:0:o;87472:301::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;87622:1:::1;87612:7;:11;87604:51;;;::::0;-1:-1:-1;;;87604:51:0;;16759:2:1;87604:51:0::1;::::0;::::1;16741:21:1::0;16798:2;16778:18;;;16771:30;16837:29;16817:18;;;16810:57;16884:18;;87604:51:0::1;16557:351:1::0;87604:51:0::1;87662:17;::::0;;:70:::1;::::0;-1:-1:-1;;;87662:70:0;;;;::::1;17603:25:1::0;;;-1:-1:-1;;;;;17664:32:1;;;17644:18;;;17637:60;17713:18;;;17706:34;;;87662:17:0::1;::::0;:37:::1;::::0;17576:18:1;;87662:70:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;87744:23;87759:7;87744:23;;;;17365:25:1::0;;17353:2;17338:18;;17219:177;87744:23:0::1;;;;;;;;87472:301:::0;;;:::o;81116:152::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;81212:23:::1;:50:::0;81116:152::o;89864:155::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;19752:9:::1;19744:38;;;;-1:-1:-1::0;;;19744:38:0::1;;;;;;;:::i;:::-;89975:13:::2;::::0;89948:8:::2;::::0;:41:::2;::::0;-1:-1:-1;;;;;89948:8:0;;::::2;::::0;89970:3;;89948:21:::2;:41::i;:::-;-1:-1:-1::0;90012:1:0::2;89996:13;:17:::0;89864:155::o;88832:229::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;88919:1:::1;88909:7;:11;88901:48;;;::::0;-1:-1:-1;;;88901:48:0;;16406:2:1;88901:48:0::1;::::0;::::1;16388:21:1::0;16445:2;16425:18;;;16418:30;-1:-1:-1;;;16464:18:1;;;16457:54;16528:18;;88901:48:0::1;16204:348:1::0;88901:48:0::1;88956:17;::::0;;89000:23:::1;::::0;88956:68:::1;::::0;-1:-1:-1;;;88956:68:0;;;;::::1;17925:25:1::0;;;17966:18;;;17959:34;-1:-1:-1;;;;;88956:17:0::1;::::0;:34:::1;::::0;17898:18:1;;88956:68:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;89036:19;89047:7;89036:19;;;;17365:25:1::0;;17353:2;17338:18;;17219:177;89036:19:0::1;;;;;;;;88832:229:::0;:::o;74507:248::-;74590:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;74603:32:::2;74615:10;74627:7;74603:11;:32::i;:::-;74642:15;::::0;:49:::2;::::0;-1:-1:-1;;;;;74642:15:0::2;74671:10;74683:7:::0;74642:28:::2;:49::i;:::-;74703:28;74711:10;74723:7;74703:28;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;74745:4:0::2;68209:1;74507:248:::0;;;:::o;69576:72::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;20022:41:::1;;;;-1:-1:-1::0;;;20022:41:0::1;;;;;;;:::i;:::-;69632:10:::2;:8;:10::i;:::-;69576:72::o:0;71881:125::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;71973:27:0;;;;;:13;:27;;;;;;;;;71966:34;;;;;;;;;;;;;;;;;;;;71881:125::o;77171:408::-;77262:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;77275:17:::2;77295:30;77314:10;77295:18;:30::i;:::-;77275:50;;77353:7;77340:9;:20;;77332:73;;;::::0;-1:-1:-1;;;77332:73:0;;9311:2:1;77332:73:0::2;::::0;::::2;9293:21:1::0;9350:2;9330:18;;;9323:30;9389:34;9369:18;;;9362:62;-1:-1:-1;;;9440:18:1;;;9433:38;9488:19;;77332:73:0::2;9109:404:1::0;77332:73:0::2;77412:15;::::0;:41:::2;::::0;-1:-1:-1;;;77412:41:0;;-1:-1:-1;;;;;77412:15:0;;::::2;::::0;:20:::2;::::0;:41:::2;::::0;77433:10:::2;::::0;77445:7;;77412:41:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;77460:57:0::2;77494:22;:9:::0;77508:7;77494:13:::2;:22::i;:::-;77460:33;:57::i;:::-;77529:26;77535:10;77547:7;77529:26;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;77569:4:0::2;::::0;77171:408;-1:-1:-1;;77171:408:0:o;84599:844::-;84746:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;84720:10:::2;68555:30;::::0;;;:20:::2;:30;::::0;;;;;::::2;;68547:69;;;;-1:-1:-1::0;;;68547:69:0::2;;;;;;;:::i;:::-;84770:8:::3;::::0;:30:::3;::::0;-1:-1:-1;;;84770:30:0;;84789:10:::3;84770:30;::::0;::::3;4118:51:1::0;84804:12:0;;-1:-1:-1;;;;;84770:8:0::3;::::0;:18:::3;::::0;4091::1;;84770:30:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;84762:92;;;;-1:-1:-1::0;;;84762:92:0::3;;;;;;;:::i;:::-;84877:8;::::0;:45:::3;::::0;-1:-1:-1;;;84877:45:0;;84896:10:::3;84877:45;::::0;::::3;4392:34:1::0;84916:4:0::3;4442:18:1::0;;;4435:43;84926:12:0;;-1:-1:-1;;;;;84877:8:0::3;::::0;:18:::3;::::0;4327::1;;84877:45:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;;84861:153;;;;-1:-1:-1::0;;;84861:153:0::3;;;;;;;:::i;:::-;85021:20;85044:30;85061:12;85044:16;:30::i;:::-;85021:53;;85104:1;85089:12;:16;85081:87;;;;-1:-1:-1::0;;;85081:87:0::3;;;;;;;:::i;:::-;85221:17;::::0;;85175:8;:79:::3;::::0;-1:-1:-1;;;;;85175:8:0;;::::3;::::0;85201:10:::3;::::0;85221:17:::3;85241:12:::0;85175:25:::3;:79::i;:::-;85261:15;::::0;:46:::3;::::0;-1:-1:-1;;;85261:46:0;;-1:-1:-1;;;;;85261:15:0;;::::3;::::0;:20:::3;::::0;:46:::3;::::0;85282:10:::3;::::0;85294:12;;85261:46:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;85341:8:0::3;::::0;85319:58:::3;::::0;::::3;::::0;::::3;::::0;-1:-1:-1;;;;;85341:8:0;;::::3;::::0;85352:10:::3;::::0;85364:12;;85319:58:::3;:::i;:::-;;;;;;;;85389:30;85394:10;85406:12;85389:30;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;85433:4:0::3;::::0;84599:844;-1:-1:-1;;;84599:844:0:o;75917:241::-;75973:7;;;76013:121;76037:12;:19;76033:23;;76013:121;;;76080:46;76090:35;76109:12;76122:1;76109:15;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;76109:15:0;76090:18;:35::i;:::-;76080:5;;:9;:46::i;:::-;76072:54;-1:-1:-1;76058:3:0;;;;:::i;:::-;;;;76013:121;;;-1:-1:-1;76147:5:0;75917:241;-1:-1:-1;75917:241:0:o;22326:103::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;22391:30:::1;22418:1;22391:18;:30::i;75613:222::-:0;75681:7;75697:27;75727:18;75735:9;75727:7;:18::i;:::-;75697:48;;75793:36;75818:10;75793:24;:36::i;:::-;-1:-1:-1;;;;;75759:31:0;;;;;;:20;:31;;;;;;:70;;;;:::i;:::-;75752:77;75613:222;-1:-1:-1;;;75613:222:0:o;81834:152::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;81930:23:::1;:50:::0;81834:152::o;89116:227::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;20022:41:::1;;;;-1:-1:-1::0;;;20022:41:0::1;;;;;;;:::i;:::-;89180:8:::2;::::0;:33:::2;::::0;-1:-1:-1;;;89180:33:0;;89207:4:::2;89180:33;::::0;::::2;4118:51:1::0;-1:-1:-1;;;;;89180:8:0;;::::2;::::0;:18:::2;::::0;4091::1;;89180:33:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;89172:83:::2;;;::::0;-1:-1:-1;;;89172:83:0;;13662:2:1;89172:83:0::2;::::0;::::2;13644:21:1::0;;;13681:18;;;13674:30;13740:34;13720:18;;;13713:62;13792:18;;89172:83:0::2;13460:356:1::0;89172:83:0::2;89264:20;21748:6:::0;-1:-1:-1;;;;;21748:6:0;;89319:18:::2;69448:71:::0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;19752:9:::1;19744:38;;;;-1:-1:-1::0;;;19744:38:0::1;;;;;;;:::i;:::-;69505:8:::2;:6;:8::i;68953:413::-:0;69032:4;21748:6;;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;68321:12:::1;::::0;-1:-1:-1;;;68321:12:0;::::1;;;68320:13;68312:68;;;::::0;-1:-1:-1;;;68312:68:0;;8488:2:1;68312:68:0::1;::::0;::::1;8470:21:1::0;8527:2;8507:18;;;8500:30;8566:34;8546:18;;;8539:62;-1:-1:-1;;;8617:18:1;;;8610:40;8667:19;;68312:68:0::1;8286:406:1::0;68312:68:0::1;69045:26:::2;69074:33;:31;:33::i;:::-;69045:62;;69143:1;69122:18;:22;69114:78;;;::::0;-1:-1:-1;;;69114:78:0;;8899:2:1;69114:78:0::2;::::0;::::2;8881:21:1::0;8938:2;8918:18;;;8911:30;8977:34;8957:18;;;8950:62;-1:-1:-1;;;9028:18:1;;;9021:41;9079:19;;69114:78:0::2;8697:407:1::0;69114:78:0::2;69199:15;::::0;-1:-1:-1;;;;;69199:15:0::2;:20;69236:4;69250:59;69294:14;:12;:14::i;:::-;69250:39;69273:15;:13;:15::i;:::-;69250:18:::0;;:22:::2;:39::i;:59::-;69199:117;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;69323:12:0::2;:19:::0;;-1:-1:-1;;;;69323:19:0::2;-1:-1:-1::0;;;69323:19:0::2;::::0;;-1:-1:-1;69338:4:0::2;68953:413:::0;:::o;88481:219::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;88572:1:::1;88562:7;:11;88554:51;;;::::0;-1:-1:-1;;;88554:51:0;;16759:2:1;88554:51:0::1;::::0;::::1;16741:21:1::0;16798:2;16778:18;;;16771:30;16837:29;16817:18;;;16810:57;16884:18;;88554:51:0::1;16557:351:1::0;88554:51:0::1;88612:17;::::0;;:47:::1;::::0;-1:-1:-1;;;88612:47:0;;;;::::1;17365:25:1::0;;;-1:-1:-1;;;;;88612:17:0::1;::::0;:38:::1;::::0;17338:18:1;;88612:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;88671:23;88686:7;88671:23;;;;17365:25:1::0;;17353:2;17338:18;;17219:177;81475:156:0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;81573:24:::1;:52:::0;81475:156::o;79144:194::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;79273:17:::1;::::0;;:59:::1;::::0;-1:-1:-1;;;79273:59:0;;-1:-1:-1;;;;;79273:17:0;;::::1;::::0;:25:::1;::::0;:59:::1;::::0;79299:13;;79314:8;;79324:7;;79273:59:::1;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;79144:194:::0;;;:::o;74039:260::-;74120:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;74133:29:::2;74142:10;74154:7;74133:8;:29::i;:::-;74169:15;::::0;:68:::2;::::0;-1:-1:-1;;;;;74169:15:0::2;74202:10;74222:4;74229:7:::0;74169:32:::2;:68::i;:::-;74249:26;74255:10;74267:7;74249:26;;;;;;;:::i;77837:515::-:0;77924:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;77953:15:::2;::::0;:46:::2;::::0;-1:-1:-1;;;77953:46:0;;77987:10:::2;77953:46;::::0;::::2;4118:51:1::0;78003:7:0;;-1:-1:-1;;;;;77953:15:0::2;::::0;:25:::2;::::0;4091:18:1;;77953:46:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:57;;77937:152;;;::::0;-1:-1:-1;;;77937:152:0;;15143:2:1;77937:152:0::2;::::0;::::2;15125:21:1::0;15182:2;15162:18;;;15155:30;15221:34;15201:18;;;15194:62;15292:31;15272:18;;;15265:59;15341:19;;77937:152:0::2;14941:425:1::0;77937:152:0::2;78096:17;::::0;-1:-1:-1;;;;;78096:17:0::2;:29;78134:10;78153:7:::0;78169:35:::2;:33;:35::i;:::-;78213:21;::::0;78096:145:::2;::::0;-1:-1:-1;;;;;;78096:145:0::2;::::0;;;;;;-1:-1:-1;;;;;5397:32:1;;;78096:145:0::2;::::0;::::2;5379:51:1::0;5446:18;;;5439:34;;;;5489:18;;;5482:34;5532:18;;;5525:34;5351:19;;78096:145:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;78248:15:0::2;::::0;:41:::2;::::0;-1:-1:-1;;;78248:41:0;;-1:-1:-1;;;;;78248:15:0;;::::2;::::0;-1:-1:-1;78248:20:0::2;::::0;-1:-1:-1;78248:41:0::2;::::0;78269:10:::2;::::0;78281:7;;78248:41:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78301:27;78308:10;78320:7;78301:27;;;;;;;:::i;69763:189::-:0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68797:30:0;::::1;;::::0;;;:20:::1;:30;::::0;;;;;69867:19;;68797:30:::1;;68796:31;68788:63;;;::::0;-1:-1:-1;;;68788:63:0;;11709:2:1;68788:63:0::1;::::0;::::1;11691:21:1::0;11748:2;11728:18;;;11721:30;-1:-1:-1;;;11767:18:1;;;11760:49;11826:18;;68788:63:0::1;11507:343:1::0;68788:63:0::1;-1:-1:-1::0;;;;;;69898:41:0::2;;::::0;;;:20:::2;:41;::::0;;;;:48;;-1:-1:-1;;69898:48:0::2;69942:4;69898:48;::::0;;69763:189::o;86647:569::-;86813:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;86787:10:::2;68555:30;::::0;;;:20:::2;:30;::::0;;;;;::::2;;68547:69;;;;-1:-1:-1::0;;;68547:69:0::2;;;;;;;:::i;:::-;86853:17:::3;::::0;;:125:::3;::::0;-1:-1:-1;;;86853:125:0;;86829:21:::3;::::0;-1:-1:-1;;;;;86853:17:0;;::::3;::::0;:60:::3;::::0;:125:::3;::::0;86922:13;;86944:10:::3;::::0;86963:8;;86853:125:::3;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87045:17;::::0;;86985:89:::3;::::0;-1:-1:-1;;;86985:89:0;;86829:149;;-1:-1:-1;;;;;;86985:39:0;;::::3;::::0;::::3;::::0;:89:::3;::::0;87025:10:::3;::::0;87045:17:::3;::::0;87065:8;;86985:89:::3;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;-1:-1:-1::0;;87081:17:0::3;::::0;;:52:::3;::::0;-1:-1:-1;;;87081:52:0;;-1:-1:-1;;;;;87081:17:0;;::::3;::::0;-1:-1:-1;87081:25:0::3;::::0;-1:-1:-1;87081:52:0::3;::::0;87107:10:::3;::::0;87119:13;;87081:52:::3;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;87145:47;87156:13;87171:10;87183:8;87145:47;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;87206:4:0::3;::::0;86647:569;-1:-1:-1;;;;86647:569:0:o;70075:198::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;68555:30:0;::::1;;::::0;;;:20:::1;:30;::::0;;;;;70183:21;;68555:30:::1;;68547:69;;;;-1:-1:-1::0;;;68547:69:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;70216:43:0::2;70262:5;70216:43:::0;;;:20:::2;:43;::::0;;;;:51;;-1:-1:-1;;70216:51:0::2;::::0;;70075:198::o;82817:138::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;82900:15:::1;:49:::0;;-1:-1:-1;;;;;;82900:49:0::1;-1:-1:-1::0;;;;;82900:49:0;;;::::1;::::0;;;::::1;::::0;;82817:138::o;83274:1170::-;83429:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;83403:10:::2;68555:30;::::0;;;:20:::2;:30;::::0;;;;;::::2;;68547:69;;;;-1:-1:-1::0;;;68547:69:0::2;;;;;;;:::i;:::-;83461:15:::3;::::0;:37:::3;::::0;-1:-1:-1;;;83461:37:0;;83487:10:::3;83461:37;::::0;::::3;4118:51:1::0;83502:12:0;;-1:-1:-1;;;;;83461:15:0::3;::::0;:25:::3;::::0;4091:18:1;;83461:37:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;83445:121;;;::::0;-1:-1:-1;;;83445:121:0;;9720:2:1;83445:121:0::3;::::0;::::3;9702:21:1::0;9759:2;9739:18;;;9732:30;9798:34;9778:18;;;9771:62;-1:-1:-1;;;9849:18:1;;;9842:32;9891:19;;83445:121:0::3;9518:398:1::0;83445:121:0::3;83589:15;::::0;:52:::3;::::0;-1:-1:-1;;;83589:52:0;;83615:10:::3;83589:52;::::0;::::3;4392:34:1::0;83635:4:0::3;4442:18:1::0;;;4435:43;83645:12:0;;-1:-1:-1;;;;;83589:15:0::3;::::0;:25:::3;::::0;4327:18:1;;83589:52:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:68;;83573:160;;;::::0;-1:-1:-1;;;83573:160:0;;7171:2:1;83573:160:0::3;::::0;::::3;7153:21:1::0;7210:2;7190:18;;;7183:30;7249:34;7229:18;;;7222:62;7320:28;7300:18;;;7293:56;7366:19;;83573:160:0::3;6969:422:1::0;83573:160:0::3;83740:24;83767:30;83784:12;83767:16;:30::i;:::-;83740:57;;83804:21;83828:55;83879:3;83828:46;83849:24;;83828:16;:20;;:46;;;;:::i;:55::-;83804:79;;83917:1;83898:16;:20;83890:86;;;::::0;-1:-1:-1;;;83890:86:0;;15984:2:1;83890:86:0::3;::::0;::::3;15966:21:1::0;16023:2;16003:18;;;15996:30;16062:34;16042:18;;;16035:62;-1:-1:-1;;;16113:18:1;;;16106:51;16174:19;;83890:86:0::3;15782:417:1::0;83890:86:0::3;83999:8;::::0;:33:::3;::::0;-1:-1:-1;;;83999:33:0;;84026:4:::3;83999:33;::::0;::::3;4118:51:1::0;84036:16:0;;-1:-1:-1;;;;;83999:8:0::3;::::0;:18:::3;::::0;4091::1;;83999:33:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;83983:133;;;::::0;-1:-1:-1;;;83983:133:0;;12057:2:1;83983:133:0::3;::::0;::::3;12039:21:1::0;12096:2;12076:18;;;12069:30;12135:34;12115:18;;;12108:62;-1:-1:-1;;;12186:18:1;;;12179:44;12240:19;;83983:133:0::3;11855:410:1::0;83983:133:0::3;84123:15;::::0;:46:::3;::::0;-1:-1:-1;;;84123:46:0;;-1:-1:-1;;;;;84123:15:0;;::::3;::::0;:20:::3;::::0;:46:::3;::::0;84144:10:::3;::::0;84156:12;;84123:46:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;84176:70:0::3;84198:10;84210:35;:16:::0;84231:13;84210:20:::3;:35::i;:::-;84176:8;::::0;-1:-1:-1;;;;;84176:8:0::3;::::0;:70;:21:::3;:70::i;:::-;84269:13;::::0;:32:::3;::::0;84287:13;84269:17:::3;:32::i;:::-;84253:13;:48:::0;84335:15:::3;::::0;84313:65:::3;::::0;::::3;::::0;::::3;::::0;-1:-1:-1;;;;;84335:15:0;;::::3;::::0;84353:10:::3;::::0;84365:12;;84313:65:::3;:::i;:::-;;;;;;;;84390:30;84395:10;84407:12;84390:30;;;;;;;:::i;82233:144::-:0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;82325:21:::1;:46:::0;82233:144::o;85598:887::-;85754:4;19498:7;;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;68147:12:::1;::::0;-1:-1:-1;;;68147:12:0;::::1;;;68139:63;;;;-1:-1:-1::0;;;68139:63:0::1;;;;;;;:::i;:::-;85728:10:::2;68555:30;::::0;;;:20:::2;:30;::::0;;;;;::::2;;68547:69;;;;-1:-1:-1::0;;;68547:69:0::2;;;;;;;:::i;:::-;85778:8:::3;::::0;:30:::3;::::0;-1:-1:-1;;;85778:30:0;;85797:10:::3;85778:30;::::0;::::3;4118:51:1::0;85812:12:0;;-1:-1:-1;;;;;85778:8:0::3;::::0;:18:::3;::::0;4091::1;;85778:30:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;85770:92;;;;-1:-1:-1::0;;;85770:92:0::3;;;;;;;:::i;:::-;85885:8;::::0;:45:::3;::::0;-1:-1:-1;;;85885:45:0;;85904:10:::3;85885:45;::::0;::::3;4392:34:1::0;85924:4:0::3;4442:18:1::0;;;4435:43;85934:12:0;;-1:-1:-1;;;;;85885:8:0::3;::::0;:18:::3;::::0;4327::1;;85885:45:0::3;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;;85869:153;;;;-1:-1:-1::0;;;85869:153:0::3;;;;;;;:::i;:::-;86029:20;86052:30;86069:12;86052:16;:30::i;:::-;86029:53;;86112:1;86097:12;:16;86089:87;;;;-1:-1:-1::0;;;86089:87:0::3;;;;;;;:::i;:::-;86183:8;::::0;:66:::3;::::0;-1:-1:-1;;;;;86183:8:0::3;86209:10;86229:4;86236:12:::0;86183:25:::3;:66::i;:::-;86256:15;::::0;:49:::3;::::0;-1:-1:-1;;;86256:49:0;;-1:-1:-1;;;;;86256:15:0;;::::3;::::0;:20:::3;::::0;:49:::3;::::0;86285:4:::3;::::0;86292:12;;86256:49:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;86312:34;86321:10;86333:12;86312:8;:34::i;:::-;86380:8;::::0;86358:58:::3;::::0;::::3;::::0;::::3;::::0;-1:-1:-1;;;;;86380:8:0;;::::3;::::0;86391:10:::3;::::0;86403:12;;86358:58:::3;:::i;:::-;;;;;;;;86428:33;86441:4;86448:12;86428:33;;;;;;;:::i;90190:172::-:0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;20022:41:::1;;;;-1:-1:-1::0;;;20022:41:0::1;;;;;;;:::i;:::-;90273:15:::2;::::0;:38:::2;::::0;-1:-1:-1;;;90273:38:0;;-1:-1:-1;;;;;4136:32:1;;;90273:38:0::2;::::0;::::2;4118:51:1::0;90273:15:0;;::::2;::::0;:33:::2;::::0;4091:18:1;;90273:38:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;90318:15:0::2;::::0;:38:::2;::::0;-1:-1:-1;;;90318:38:0;;-1:-1:-1;;;;;4136:32:1;;;90318:38:0::2;::::0;::::2;4118:51:1::0;90318:15:0;;::::2;::::0;-1:-1:-1;90318:33:0::2;::::0;-1:-1:-1;4091:18:1;;90318:38:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;90190:172:::0;:::o;89520:220::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;20022:41:::1;;;;-1:-1:-1::0;;;20022:41:0::1;;;;;;;:::i;:::-;89633:46:::2;::::0;-1:-1:-1;;;89633:46:0;;89673:4:::2;89633:46;::::0;::::2;4118:51:1::0;89615:15:0::2;::::0;-1:-1:-1;;;;;89633:31:0;::::2;::::0;::::2;::::0;4091:18:1;;89633:46:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89615:64:::0;-1:-1:-1;89686:48:0::2;-1:-1:-1::0;;;;;89686:34:0;::::2;89721:3:::0;89615:64;89686:34:::2;:48::i;:::-;89608:132;89520:220:::0;;:::o;79412:470::-;79476:7;79492:18;79513:89;79542:17;;;;;;;;;-1:-1:-1;;;;;79542:17:0;-1:-1:-1;;;;;79542:51:0;;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79513:16;:14;:16::i;:::-;:20;;:89::i;:::-;79492:110;;79638:13;;79625:10;:26;79609:134;;;;-1:-1:-1;;;79609:134:0;;8005:2:1;79609:134:0;;;7987:21:1;8044:2;8024:18;;;8017:30;8083:34;8063:18;;;8056:62;8154:34;8134:18;;;8127:62;-1:-1:-1;;;8205:19:1;;;8198:41;8256:19;;79609:134:0;7803:478:1;79609:134:0;79854:13;;79785:17;;;:53;;;-1:-1:-1;;;79785:53:0;;;;79764:112;;79854:13;79764:75;;-1:-1:-1;;;;;79785:17:0;;:51;;:53;;;;;;;;;;;:17;:53;;;;;;;;;;79764:75;:79;;:112::i;:::-;79750:126;;;79412:470;:::o;76252:155::-;76318:7;76341:60;76371:15;;;;;;;;;-1:-1:-1;;;;;76371:15:0;-1:-1:-1;;;;;76371:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76341:25;:23;:25::i;:60::-;76334:67;;76252:155;:::o;80181:312::-;80245:7;80261:28;80292:15;;;;;;;;;-1:-1:-1;;;;;80292:15:0;-1:-1:-1;;;;;80292:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80261:60;;80328:39;80370:33;:31;:33::i;:::-;80328:75;-1:-1:-1;80417:70:0;80466:20;80417:44;:7;80328:75;80417:11;:44::i;70783:232::-;70845:4;70851:7;70872:9;70867:119;70891:12;:19;70887:23;;70867:119;;;70945:12;70958:1;70945:15;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;70933:27:0;;;70945:15;;70933:27;70929:49;;;70970:4;;70976:1;;-1:-1:-1;70783:232:0;-1:-1:-1;;70783:232:0:o;70929:49::-;70912:6;70917:1;70912:6;;:::i;:::-;;;70867:119;;;-1:-1:-1;71000:5:0;;;;-1:-1:-1;70783:232:0;-1:-1:-1;;70783:232:0:o;88010:311::-;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;88156:1:::1;88146:7;:11;88138:48;;;::::0;-1:-1:-1;;;88138:48:0;;16406:2:1;88138:48:0::1;::::0;::::1;16388:21:1::0;16445:2;16425:18;;;16418:30;-1:-1:-1;;;16464:18:1;;;16457:54;16528:18;;88138:48:0::1;16204:348:1::0;88138:48:0::1;88193:17;::::0;;88260:23:::1;::::0;88193:91:::1;::::0;-1:-1:-1;;;88193:91:0;;;;::::1;18235:25:1::0;;;18276:18;;;18269:34;;;-1:-1:-1;;;;;18339:32:1;;;18319:18;;;18312:60;18388:18;;;18381:34;;;;88193:17:0::1;::::0;:33:::1;::::0;18207:19:1;;88193:91:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;88296:19;88307:7;88296:19;;;;17365:25:1::0;;17353:2;17338:18;;17219:177;22584:201:0;21721:7;21748:6;-1:-1:-1;;;;;21748:6:0;18161:10;21895:23;21887:68;;;;-1:-1:-1;;;21887:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;22673:22:0;::::1;22665:73;;;::::0;-1:-1:-1;;;22665:73:0;;7598:2:1;22665:73:0::1;::::0;::::1;7580:21:1::0;7637:2;7617:18;;;7610:30;7676:34;7656:18;;;7649:62;-1:-1:-1;;;7727:18:1;;;7720:36;7773:19;;22665:73:0::1;7396:402:1::0;22665:73:0::1;22749:28;22768:8;22749:18;:28::i;:::-;22584:201:::0;:::o;75060:152::-;75136:21;:19;:21::i;:::-;75185:10;75164:32;;;;:20;:32;;;;;:42;75060:152::o;12116:98::-;12174:7;12201:5;12205:1;12201;:5;:::i;12515:98::-;12573:7;12600:5;12604:1;12600;:5;:::i;58388:211::-;58505:86;58525:5;58555:23;;;58580:2;58584:5;58532:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;58532:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;58532:58:0;-1:-1:-1;;;;;;58532:58:0;;;;;;;;;;58505:19;:86::i;73030:394::-;73135:6;73108:16;73116:7;73108;:16::i;:::-;:23;:33;;73100:84;;;;-1:-1:-1;;;73100:84:0;;10957:2:1;73100:84:0;;;10939:21:1;10996:2;10976:18;;;10969:30;11035:34;11015:18;;;11008:62;-1:-1:-1;;;11086:18:1;;;11079:36;11132:19;;73100:84:0;10755:402:1;73100:84:0;-1:-1:-1;;;;;73195:22:0;;;;;;:13;:22;;;;;:29;73191:63;;73231:23;73246:7;73231:14;:23::i;:::-;-1:-1:-1;;;;;73294:22:0;;;;;;:13;:22;;;;;73261:56;;73285:7;;73261:23;:56::i;:::-;73349:69;;;;;;;;-1:-1:-1;;;;;73359:22:0;;-1:-1:-1;73359:22:0;;;:13;:22;;;;;;:29;73349:69;;73359:41;;73393:6;73359:33;:41::i;:::-;73349:69;;73402:15;73349:69;;;;;-1:-1:-1;;;;;73324:22:0;;;-1:-1:-1;73324:22:0;;;:13;:22;;;;;:94;;;;;;;;;;;;;;;-1:-1:-1;73030:394:0:o;20486:120::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;20022:41;;;;-1:-1:-1;;;20022:41:0;;;;;;;:::i;:::-;20555:5:::1;20545:15:::0;;-1:-1:-1;;;;20545:15:0::1;::::0;;20576:22:::1;18161:10:::0;20585:12:::1;20576:22;::::0;-1:-1:-1;;;;;4136:32:1;;;4118:51;;4106:2;4091:18;20576:22:0::1;;;;;;;20486:120::o:0;11759:98::-;11817:7;11844:5;11848:1;11844;:5;:::i;58607:248::-;58751:96;58771:5;58801:27;;;58830:4;58836:2;58840:5;58778:68;;;;;;;;;;:::i;58751:96::-;58607:248;;;;:::o;11378:98::-;11436:7;11463:5;11467:1;11463;:5;:::i;22945:191::-;23019:16;23038:6;;-1:-1:-1;;;;;23055:17:0;;;-1:-1:-1;;;;;;23055:17:0;;;;;;23088:40;;23038:6;;;;;;;23088:40;;23019:16;23088:40;23008:128;22945:191;:::o;75218:272::-;75300:7;75330:154;75475:8;75330:130;75456:3;75330:111;75417:23;;75330:72;75368:33;75388:6;:12;;;75368:15;:19;;:33;;;;:::i;:::-;75330:23;;;:37;:72::i;:::-;:86;;:111::i;20227:118::-;19474:4;19498:7;-1:-1:-1;;;19498:7:0;;;;19752:9;19744:38;;;;-1:-1:-1;;;19744:38:0;;;;;;;:::i;:::-;20287:7:::1;:14:::0;;-1:-1:-1;;;;20287:14:0::1;-1:-1:-1::0;;;20287:14:0::1;::::0;;20317:20:::1;20324:12;18161:10:::0;;18081:98;82605:99;82652:7;82675:23;82696:1;82683:2;82675:23;:::i;82440:101::-;82488:7;82511:24;82532:2;82519;82511:24;:::i;72555:300::-;-1:-1:-1;;;;;72626:22:0;;;;;;:13;:22;;;;;:29;72622:63;;72662:23;72677:7;72662:14;:23::i;:::-;-1:-1:-1;;;;;72725:22:0;;;;;;:13;:22;;;;;72692:56;;72716:7;;72692:23;:56::i;:::-;72780:69;;;;;;;;-1:-1:-1;;;;;72790:22:0;;-1:-1:-1;72790:22:0;;;:13;:22;;;;;;:29;72780:69;;72790:41;;72824:6;72790:33;:41::i;79936:111::-;80008:8;;:33;;-1:-1:-1;;;80008:33:0;;80035:4;80008:33;;;4118:51:1;79985:7:0;;-1:-1:-1;;;;;80008:8:0;;:18;;4091::1;;80008:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72104:286::-;72169:10;72155:25;;;;:13;:25;;;;;:32;72151:69;;72194:26;72209:10;72194:14;:26::i;:::-;72251:10;72263:25;;;;:13;:25;;;;;72227:62;;72251:10;72227:23;:62::i;:::-;72324:60;;;;;;;;72348:10;-1:-1:-1;72334:25:0;;;:13;:25;;;;;;;:32;;72324:60;;72368:15;72324:60;;;;;;72296:25;;;;;;;:88;;;;;-1:-1:-1;72296:88:0;;;;72104:286::o;60961:716::-;61385:23;61411:69;61439:4;61411:69;;;;;;;;;;;;;;;;;61419:5;-1:-1:-1;;;;;61411:27:0;;;:69;;;;;:::i;:::-;61495:17;;61385:95;;-1:-1:-1;61495:21:0;61491:179;;61592:10;61581:30;;;;;;;;;;;;:::i;:::-;61573:85;;;;-1:-1:-1;;;61573:85:0;;15573:2:1;61573:85:0;;;15555:21:1;15612:2;15592:18;;;15585:30;15651:34;15631:18;;;15624:62;-1:-1:-1;;;15702:18:1;;;15695:40;15752:19;;61573:85:0;15371:406:1;71118:180:0;71181:19;71206:27;71220:12;71206:13;:27::i;:::-;71180:53;;;71245:14;71240:52;;71261:12;:31;;;;;;;-1:-1:-1;71261:31:0;;;;;;;;-1:-1:-1;;;;;;71261:31:0;-1:-1:-1;;;;;71261:31:0;;;;;71240:52;71173:125;71118:180;:::o;73556:289::-;73689:32;;;;;;;;;;;;;;;;;;;;;73648:38;;73689:32;;:24;:32::i;:::-;-1:-1:-1;;;;;73760:29:0;;;;;;:20;:29;;;;;;73648:73;;-1:-1:-1;73760:79:0;;73648:73;73760:33;:79::i;:::-;-1:-1:-1;;;;;73728:29:0;;;;;;;:20;:29;;;;;:111;;;;-1:-1:-1;;73556:289:0:o;35412:229::-;35549:12;35581:52;35603:6;35611:4;35617:1;35620:12;35549;-1:-1:-1;;;;;32962:19:0;;;36819:60;;;;-1:-1:-1;;;36819:60:0;;14378:2:1;36819:60:0;;;14360:21:1;14417:2;14397:18;;;14390:30;14456:31;14436:18;;;14429:59;14505:18;;36819:60:0;14176:353:1;36819:60:0;36893:12;36907:23;36934:6;-1:-1:-1;;;;;36934:11:0;36953:5;36960:4;36934:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36892:73;;;;36983:51;37000:7;37009:10;37021:12;36983:16;:51::i;:::-;36976:58;36532:510;-1:-1:-1;;;;;;;36532:510:0:o;39218:712::-;39368:12;39397:7;39393:530;;;-1:-1:-1;39428:10:0;39421:17;;39393:530;39542:17;;:21;39538:374;;39740:10;39734:17;39801:15;39788:10;39784:2;39780:19;39773:44;39538:374;39883:12;39876:20;;-1:-1:-1;;;39876:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;192:186;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;383:260::-;451:6;459;512:2;500:9;491:7;487:23;483:32;480:52;;;528:1;525;518:12;480:52;551:29;570:9;551:29;:::i;:::-;541:39;;599:38;633:2;622:9;618:18;599:38;:::i;:::-;589:48;;383:260;;;;;:::o;648:328::-;725:6;733;741;794:2;782:9;773:7;769:23;765:32;762:52;;;810:1;807;800:12;762:52;833:29;852:9;833:29;:::i;:::-;823:39;;881:38;915:2;904:9;900:18;881:38;:::i;:::-;871:48;;966:2;955:9;951:18;938:32;928:42;;648:328;;;;;:::o;981:1138::-;1076:6;1084;1092;1100;1153:3;1141:9;1132:7;1128:23;1124:33;1121:53;;;1170:1;1167;1160:12;1121:53;1193:29;1212:9;1193:29;:::i;:::-;1183:39;;1241:38;1275:2;1264:9;1260:18;1241:38;:::i;:::-;1231:48;;1326:2;1315:9;1311:18;1298:32;1288:42;;1381:2;1370:9;1366:18;1353:32;1404:18;1445:2;1437:6;1434:14;1431:34;;;1461:1;1458;1451:12;1431:34;1499:6;1488:9;1484:22;1474:32;;1544:7;1537:4;1533:2;1529:13;1525:27;1515:55;;1566:1;1563;1556:12;1515:55;1602:2;1589:16;1624:2;1620;1617:10;1614:36;;;1630:18;;:::i;:::-;1705:2;1699:9;1673:2;1759:13;;-1:-1:-1;;1755:22:1;;;1779:2;1751:31;1747:40;1735:53;;;1803:18;;;1823:22;;;1800:46;1797:72;;;1849:18;;:::i;:::-;1889:10;1885:2;1878:22;1924:2;1916:6;1909:18;1964:7;1959:2;1954;1950;1946:11;1942:20;1939:33;1936:53;;;1985:1;1982;1975:12;1936:53;2041:2;2036;2032;2028:11;2023:2;2015:6;2011:15;1998:46;2086:1;2081:2;2076;2068:6;2064:15;2060:24;2053:35;2107:6;2097:16;;;;;;;981:1138;;;;;;;:::o;2124:254::-;2192:6;2200;2253:2;2241:9;2232:7;2228:23;2224:32;2221:52;;;2269:1;2266;2259:12;2221:52;2292:29;2311:9;2292:29;:::i;:::-;2282:39;2368:2;2353:18;;;;2340:32;;-1:-1:-1;;;2124:254:1:o;2383:277::-;2450:6;2503:2;2491:9;2482:7;2478:23;2474:32;2471:52;;;2519:1;2516;2509:12;2471:52;2551:9;2545:16;2604:5;2597:13;2590:21;2583:5;2580:32;2570:60;;2626:1;2623;2616:12;2665:180;2724:6;2777:2;2765:9;2756:7;2752:23;2748:32;2745:52;;;2793:1;2790;2783:12;2745:52;-1:-1:-1;2816:23:1;;2665:180;-1:-1:-1;2665:180:1:o;2850:184::-;2920:6;2973:2;2961:9;2952:7;2948:23;2944:32;2941:52;;;2989:1;2986;2979:12;2941:52;-1:-1:-1;3012:16:1;;2850:184;-1:-1:-1;2850:184:1:o;3039:322::-;3116:6;3124;3132;3185:2;3173:9;3164:7;3160:23;3156:32;3153:52;;;3201:1;3198;3191:12;3153:52;3237:9;3224:23;3214:33;;3266:38;3300:2;3289:9;3285:18;3266:38;:::i;3366:322::-;3443:6;3451;3459;3512:2;3500:9;3491:7;3487:23;3483:32;3480:52;;;3528:1;3525;3518:12;3480:52;3564:9;3551:23;3541:33;;3621:2;3610:9;3606:18;3593:32;3583:42;;3644:38;3678:2;3667:9;3663:18;3644:38;:::i;:::-;3634:48;;3366:322;;;;;:::o;3693:274::-;3822:3;3860:6;3854:13;3876:53;3922:6;3917:3;3910:4;3902:6;3898:17;3876:53;:::i;:::-;3945:16;;;;;3693:274;-1:-1:-1;;3693:274:1:o;4489:375::-;-1:-1:-1;;;;;4747:15:1;;;4729:34;;4799:15;;;;4794:2;4779:18;;4772:43;4846:2;4831:18;;4824:34;;;;4679:2;4664:18;;4489:375::o;4869:274::-;-1:-1:-1;;;;;5061:32:1;;;;5043:51;;5125:2;5110:18;;5103:34;5031:2;5016:18;;4869:274::o;6232:383::-;6381:2;6370:9;6363:21;6344:4;6413:6;6407:13;6456:6;6451:2;6440:9;6436:18;6429:34;6472:66;6531:6;6526:2;6515:9;6511:18;6506:2;6498:6;6494:15;6472:66;:::i;:::-;6599:2;6578:15;-1:-1:-1;;6574:29:1;6559:45;;;;6606:2;6555:54;;6232:383;-1:-1:-1;;6232:383:1:o;6620:344::-;6822:2;6804:21;;;6861:2;6841:18;;;6834:30;-1:-1:-1;;;6895:2:1;6880:18;;6873:50;6955:2;6940:18;;6620:344::o;9921:422::-;10123:2;10105:21;;;10162:2;10142:18;;;10135:30;10201:34;10196:2;10181:18;;10174:62;10272:28;10267:2;10252:18;;10245:56;10333:3;10318:19;;9921:422::o;11162:340::-;11364:2;11346:21;;;11403:2;11383:18;;;11376:30;-1:-1:-1;;;11437:2:1;11422:18;;11415:46;11493:2;11478:18;;11162:340::o;12270:422::-;12472:2;12454:21;;;12511:2;12491:18;;;12484:30;12550:34;12545:2;12530:18;;12523:62;12621:28;12616:2;12601:18;;12594:56;12682:3;12667:19;;12270:422::o;12697:397::-;12899:2;12881:21;;;12938:2;12918:18;;;12911:30;12977:34;12972:2;12957:18;;12950:62;-1:-1:-1;;;13043:2:1;13028:18;;13021:31;13084:3;13069:19;;12697:397::o;13099:356::-;13301:2;13283:21;;;13320:18;;;13313:30;13379:34;13374:2;13359:18;;13352:62;13446:2;13431:18;;13099:356::o;13821:350::-;14023:2;14005:21;;;14062:2;14042:18;;;14035:30;14101:28;14096:2;14081:18;;14074:56;14162:2;14147:18;;13821:350::o;14534:402::-;14736:2;14718:21;;;14775:2;14755:18;;;14748:30;14814:34;14809:2;14794:18;;14787:62;-1:-1:-1;;;14880:2:1;14865:18;;14858:36;14926:3;14911:19;;14534:402::o;18750:128::-;18790:3;18821:1;18817:6;18814:1;18811:13;18808:39;;;18827:18;;:::i;:::-;-1:-1:-1;18863:9:1;;18750:128::o;18883:217::-;18923:1;18949;18939:132;;18993:10;18988:3;18984:20;18981:1;18974:31;19028:4;19025:1;19018:15;19056:4;19053:1;19046:15;18939:132;-1:-1:-1;19085:9:1;;18883:217::o;19105:422::-;19194:1;19237:5;19194:1;19251:270;19272:7;19262:8;19259:21;19251:270;;;19331:4;19327:1;19323:6;19319:17;19313:4;19310:27;19307:53;;;19340:18;;:::i;:::-;19390:7;19380:8;19376:22;19373:55;;;19410:16;;;;19373:55;19489:22;;;;19449:15;;;;19251:270;;;19255:3;19105:422;;;;;:::o;19532:131::-;19592:5;19621:36;19648:8;19642:4;19717:5;19747:8;19737:80;;-1:-1:-1;19788:1:1;19802:5;;19737:80;19836:4;19826:76;;-1:-1:-1;19873:1:1;19887:5;;19826:76;19918:4;19936:1;19931:59;;;;20004:1;19999:130;;;;19911:218;;19931:59;19961:1;19952:10;;19975:5;;;19999:130;20036:3;20026:8;20023:17;20020:43;;;20043:18;;:::i;:::-;-1:-1:-1;;20099:1:1;20085:16;;20114:5;;19911:218;;20213:2;20203:8;20200:16;20194:3;20188:4;20185:13;20181:36;20175:2;20165:8;20162:16;20157:2;20151:4;20148:12;20144:35;20141:77;20138:159;;;-1:-1:-1;20250:19:1;;;20282:5;;20138:159;20329:34;20354:8;20348:4;20329:34;:::i;:::-;20399:6;20395:1;20391:6;20387:19;20378:7;20375:32;20372:58;;;20410:18;;:::i;:::-;20448:20;;19668:806;-1:-1:-1;;;19668:806:1:o;20479:168::-;20519:7;20585:1;20581;20577:6;20573:14;20570:1;20567:21;20562:1;20555:9;20548:17;20544:45;20541:71;;;20592:18;;:::i;:::-;-1:-1:-1;20632:9:1;;20479:168::o;20652:125::-;20692:4;20720:1;20717;20714:8;20711:34;;;20725:18;;:::i;:::-;-1:-1:-1;20762:9:1;;20652:125::o;20782:258::-;20854:1;20864:113;20878:6;20875:1;20872:13;20864:113;;;20954:11;;;20948:18;20935:11;;;20928:39;20900:2;20893:10;20864:113;;;20995:6;20992:1;20989:13;20986:48;;;-1:-1:-1;;21030:1:1;21012:16;;21005:27;20782:258::o;21045:135::-;21084:3;-1:-1:-1;;21105:17:1;;21102:43;;;21125:18;;:::i;:::-;-1:-1:-1;21172:1:1;21161:13;;21045:135::o;21185:127::-;21246:10;21241:3;21237:20;21234:1;21227:31;21277:4;21274:1;21267:15;21301:4;21298:1;21291:15;21317:127;21378:10;21373:3;21369:20;21366:1;21359:31;21409:4;21406:1;21399:15;21433:4;21430:1;21423:15;21449:127;21510:10;21505:3;21501:20;21498:1;21491:31;21541:4;21538:1;21531:15;21565:4;21562:1;21555:15

Swarm Source

ipfs://1297941ff9e3ac8ecb02dfe993e62281a7358bf7853d004ad7cdd7465c339c80

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.