{
  "address": "0xfe672A4b063b1895b2f6531a78a69c014614B2D8",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_peronioV1Address",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_peronioV2Address",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "timestamp",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "oldPe",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "usdc",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "newPe",
          "type": "uint256"
        }
      ],
      "name": "Migrated",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "migrate",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "usdc",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "pe",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "peronioV1Address",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "peronioV2Address",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "quote",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "usdc",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "pe",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceId",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0xacb6c580f9c3d06526991bbfd90be14bca175364d006fb8f074863b203a35f34",
  "receipt": {
    "to": null,
    "from": "0x4BADCf0DCeaAD060f86D9b34c9E118c8319945AE",
    "contractAddress": "0xfe672A4b063b1895b2f6531a78a69c014614B2D8",
    "transactionIndex": 38,
    "gasUsed": "1503301",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000108000000000000000000000200000000002000000000000000000000000800002000000000000000100000000000000000000000000000000000000000040000000000000000180000000000000000001008000000000000400000000000000000002000000000000840000000000220000040000100000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000010008000000000000000000000000000000000000000000000000000100000",
    "blockHash": "0xecf0c50cdff1eb3a6e819912d6eba3519ca55054c55d74913c9151fd10f795b3",
    "transactionHash": "0xacb6c580f9c3d06526991bbfd90be14bca175364d006fb8f074863b203a35f34",
    "logs": [
      {
        "transactionIndex": 38,
        "blockNumber": 33279703,
        "transactionHash": "0xacb6c580f9c3d06526991bbfd90be14bca175364d006fb8f074863b203a35f34",
        "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
        "topics": [
          "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
          "0x000000000000000000000000fe672a4b063b1895b2f6531a78a69c014614b2d8",
          "0x00000000000000000000000078a486306d15e7111cca541f2f1307a1cfcaf5c4"
        ],
        "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
        "logIndex": 204,
        "blockHash": "0xecf0c50cdff1eb3a6e819912d6eba3519ca55054c55d74913c9151fd10f795b3"
      },
      {
        "transactionIndex": 38,
        "blockNumber": 33279703,
        "transactionHash": "0xacb6c580f9c3d06526991bbfd90be14bca175364d006fb8f074863b203a35f34",
        "address": "0x0000000000000000000000000000000000001010",
        "topics": [
          "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
          "0x0000000000000000000000000000000000000000000000000000000000001010",
          "0x0000000000000000000000004badcf0dceaad060f86d9b34c9e118c8319945ae",
          "0x00000000000000000000000026c80cc193b27d73d2c40943acec77f4da2c5bd8"
        ],
        "data": "0x00000000000000000000000000000000000000000000000000a039542edd5c000000000000000000000000000000000000000000000000d347bb5fe37ad22d3a000000000000000000000000000000000000000000005633ba5c90c4336f65900000000000000000000000000000000000000000000000d3471b268f4bf4d13a000000000000000000000000000000000000000000005633bafcca18624cc190",
        "logIndex": 205,
        "blockHash": "0xecf0c50cdff1eb3a6e819912d6eba3519ca55054c55d74913c9151fd10f795b3"
      }
    ],
    "blockNumber": 33279703,
    "cumulativeGasUsed": "10589170",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xc2768beF7a6BB57F0FfA169a9ED4017c09696FF1",
    "0x78a486306D15E7111cca541F2f1307a1cFCaF5C4"
  ],
  "numDeployments": 2,
  "solcInputHash": "9e65e83c249b1715b9679e816c39ce68",
  "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_peronioV1Address\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_peronioV2Address\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldPe\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"usdc\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newPe\",\"type\":\"uint256\"}],\"name\":\"Migrated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"migrate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"usdc\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pe\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"peronioV1Address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"peronioV2Address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"usdc\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pe\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_peronioV1Address\":\"The address of the old PE contract\",\"_peronioV2Address\":\"The address of the new PE contract\"}},\"migrate(uint256)\":{\"custom:emit\":\"Migrated\",\"params\":{\"amount\":\"The number of PE tokens to withdraw from the old contract\"},\"returns\":{\"pe\":\" The number of PE tokens minted on the new contract\",\"usdc\":\" The number of USDC tokens withdrawn from the old contract\"}},\"quote(uint256)\":{\"params\":{\"amount\":\"The number of PE tokens to withdraw from the old contract\"},\"returns\":{\"pe\":\" The number of PE tokens to mint on the new contract\",\"usdc\":\" The number of USDC tokens to withdraw from the old contract\"}},\"supportsInterface(bytes4)\":{\"params\":{\"interfaceId\":\"Interface ID to check against\"},\"returns\":{\"_0\":\"Whether the provided interface ID is supported\"}}},\"stateVariables\":{\"peronioV1Address\":{\"return\":\"The address in question\",\"returns\":{\"_0\":\"The address in question\"}},\"peronioV2Address\":{\"return\":\"The address in question\",\"returns\":{\"_0\":\"The address in question\"}}},\"version\":1},\"userdoc\":{\"events\":{\"Migrated(uint256,uint256,uint256,uint256)\":{\"notice\":\"Emitted upon migration\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Construct a new Peronio migrator\"},\"migrate(uint256)\":{\"notice\":\"Migrate the given number of PE tokens from the old contract to the new one\"},\"peronioV1Address()\":{\"notice\":\"Retrieve the old version's address\"},\"peronioV2Address()\":{\"notice\":\"Retrieve the new version's address\"},\"quote(uint256)\":{\"notice\":\"Retrieve the number of USDC tokens to withdraw from the old contract, and the number of OE tokens to mint on the new one\"},\"supportsInterface(bytes4)\":{\"notice\":\"Implementation of the IERC165 interface\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/migrations/Migrator.sol\":\"Migrator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IERC165).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts_latest/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts_latest/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    enum Rounding {\\n        Down, // Toward negative infinity\\n        Up, // Toward infinity\\n        Zero // Toward zero\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a >= b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a == 0 ? 0 : (a - 1) / b + 1;\\n    }\\n\\n    /**\\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n     * with further edits by Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(\\n        uint256 x,\\n        uint256 y,\\n        uint256 denominator\\n    ) internal pure returns (uint256 result) {\\n        unchecked {\\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n            // variables such that product = prod1 * 2^256 + prod0.\\n            uint256 prod0; // Least significant 256 bits of the product\\n            uint256 prod1; // Most significant 256 bits of the product\\n            assembly {\\n                let mm := mulmod(x, y, not(0))\\n                prod0 := mul(x, y)\\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n            }\\n\\n            // Handle non-overflow cases, 256 by 256 division.\\n            if (prod1 == 0) {\\n                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n            require(denominator > prod1);\\n\\n            ///////////////////////////////////////////////\\n            // 512 by 256 division.\\n            ///////////////////////////////////////////////\\n\\n            // Make division exact by subtracting the remainder from [prod1 prod0].\\n            uint256 remainder;\\n            assembly {\\n                // Compute remainder using mulmod.\\n                remainder := mulmod(x, y, denominator)\\n\\n                // Subtract 256 bit number from 512 bit number.\\n                prod1 := sub(prod1, gt(remainder, prod0))\\n                prod0 := sub(prod0, remainder)\\n            }\\n\\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n            // See https://cs.stackexchange.com/q/138556/92363.\\n\\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\\n            uint256 twos = denominator & (~denominator + 1);\\n            assembly {\\n                // Divide denominator by twos.\\n                denominator := div(denominator, twos)\\n\\n                // Divide [prod1 prod0] by twos.\\n                prod0 := div(prod0, twos)\\n\\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n                twos := add(div(sub(0, twos), twos), 1)\\n            }\\n\\n            // Shift in bits from prod1 into prod0.\\n            prod0 |= prod1 * twos;\\n\\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n            // four bits. That is, denominator * inv = 1 mod 2^4.\\n            uint256 inverse = (3 * denominator) ^ 2;\\n\\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n            // in modular arithmetic, doubling the correct bits in each step.\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n            // is no longer required.\\n            result = prod0 * inverse;\\n            return result;\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n     */\\n    function mulDiv(\\n        uint256 x,\\n        uint256 y,\\n        uint256 denominator,\\n        Rounding rounding\\n    ) internal pure returns (uint256) {\\n        uint256 result = mulDiv(x, y, denominator);\\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n            result += 1;\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\\n     *\\n     * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n     */\\n    function sqrt(uint256 a) internal pure returns (uint256) {\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n        // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n        // `msb(a) <= a < 2*msb(a)`.\\n        // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\\n        // This gives `2**k < a <= 2**(k+1)` \\u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\\n        // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\\n        // good first aproximation of `sqrt(a)` with at least 1 correct bit.\\n        uint256 result = 1;\\n        uint256 x = a;\\n        if (x >> 128 > 0) {\\n            x >>= 128;\\n            result <<= 64;\\n        }\\n        if (x >> 64 > 0) {\\n            x >>= 64;\\n            result <<= 32;\\n        }\\n        if (x >> 32 > 0) {\\n            x >>= 32;\\n            result <<= 16;\\n        }\\n        if (x >> 16 > 0) {\\n            x >>= 16;\\n            result <<= 8;\\n        }\\n        if (x >> 8 > 0) {\\n            x >>= 8;\\n            result <<= 4;\\n        }\\n        if (x >> 4 > 0) {\\n            x >>= 4;\\n            result <<= 2;\\n        }\\n        if (x >> 2 > 0) {\\n            result <<= 1;\\n        }\\n\\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n        // into the expected uint128 result.\\n        unchecked {\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            return min(result, a / result);\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates sqrt(a), following the selected rounding direction.\\n     */\\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n        uint256 result = sqrt(a);\\n        if (rounding == Rounding.Up && result * result < a) {\\n            result += 1;\\n        }\\n        return result;\\n    }\\n}\\n\",\"keccak256\":\"0xd15c3e400531f00203839159b2b8e7209c5158b35618f570c695b7e47f12e9f0\",\"license\":\"MIT\"},\"contracts/IPeronio.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\n/**\\n * Type representing an USDC token quantity\\n *\\n */\\ntype UsdcQuantity is uint256;\\n\\n/**\\n * Type representing a MAI token quantity\\n *\\n */\\ntype MaiQuantity is uint256;\\n\\n/**\\n * Type representing an LP USDC/MAI token quantity\\n *\\n */\\ntype LpQuantity is uint256;\\n\\n/**\\n * Type representing a PE token quantity\\n *\\n */\\ntype PeQuantity is uint256;\\n\\n/**\\n * Type representing a QI token quantity\\n *\\n */\\ntype QiQuantity is uint256;\\n\\n/**\\n * Type representing a ratio of PE/USD tokens (always represented using `DECIMALS` decimals)\\n *\\n */\\ntype PePerUsdcQuantity is uint256;\\n\\n/**\\n * Type representing a ratio of USD/PE tokens (always represented using `DECIMALS` decimals)\\n *\\n */\\ntype UsdcPerPeQuantity is uint256;\\n\\n/**\\n * Type representing an adimensional ratio, expressed with 6 decimals\\n *\\n */\\ntype RatioWith6Decimals is uint256;\\n\\n/**\\n * Type representing a role ID\\n *\\n */\\ntype RoleId is bytes32;\\n\\ninterface IPeronio {\\n    // --- Events ---------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Emitted upon initialization of the Peronio contract\\n     *\\n     * @param owner  The address initializing the contract\\n     * @param collateral  The number of USDC tokens used as collateral\\n     * @param startingRatio  The number of PE tokens per USDC token the vault is initialized with\\n     */\\n    event Initialized(address owner, UsdcQuantity collateral, PePerUsdcQuantity startingRatio);\\n\\n    /**\\n     * Emitted upon minting PE tokens\\n     *\\n     * @param to  The address where minted PE tokens get transferred to\\n     * @param collateralAmount  The number of USDC tokens used as collateral in this minting\\n     * @param tokenAmount  Amount of PE tokens minted\\n     */\\n    event Minted(address indexed to, UsdcQuantity collateralAmount, PeQuantity tokenAmount);\\n\\n    /**\\n     * Emitted upon collateral withdrawal\\n     *\\n     * @param to  Address where the USDC token withdrawal is directed\\n     * @param collateralAmount  The number of USDC tokens withdrawn\\n     * @param tokenAmount  The number of PE tokens burnt\\n     */\\n    event Withdrawal(address indexed to, UsdcQuantity collateralAmount, PeQuantity tokenAmount);\\n\\n    /**\\n     * Emitted upon liquidity withdrawal\\n     *\\n     * @param to  Address where the USDC token withdrawal is directed\\n     * @param lpAmount  The number of LP USDC/MAI tokens withdrawn\\n     * @param tokenAmount  The number of PE tokens burnt\\n     */\\n    event LiquidityWithdrawal(address indexed to, LpQuantity lpAmount, PeQuantity tokenAmount);\\n\\n    /**\\n     * Emitted upon the markup fee being updated\\n     *\\n     * @param operator  Address of the one updating the markup fee\\n     * @param markupFee  New markup fee\\n     */\\n    event MarkupFeeUpdated(address operator, RatioWith6Decimals markupFee);\\n\\n    /**\\n     * Emitted upon compounding rewards from QiDao's Farm back into the vault\\n     *\\n     * @param qi  Number of awarded QI tokens\\n     * @param usdc  Equivalent number of USDC tokens\\n     * @param lp  Number of LP USDC/MAI tokens re-invested\\n     */\\n    event CompoundRewards(QiQuantity qi, UsdcQuantity usdc, LpQuantity lp);\\n\\n    // --- Roles - Automatic ----------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the hash identifying the role responsible for updating the markup fee\\n     *\\n     * @return roleId  The role hash in question\\n     */\\n    function MARKUP_ROLE() external view returns (RoleId roleId); // solhint-disable-line func-name-mixedcase\\n\\n    /**\\n     * Return the hash identifying the role responsible for compounding rewards\\n     *\\n     * @return roleId  The role hash in question\\n     */\\n    function REWARDS_ROLE() external view returns (RoleId roleId); // solhint-disable-line func-name-mixedcase\\n\\n    /**\\n     * Return the hash identifying the role responsible for migrating between versions\\n     *\\n     * @return roleId  The role hash in question\\n     */\\n    function MIGRATOR_ROLE() external view returns (RoleId roleId); // solhint-disable-line func-name-mixedcase\\n\\n    // --- Addresses - Automatic ------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the address used for the USDC tokens in vault\\n     *\\n     * @return  The address in question\\n     */\\n    function usdcAddress() external view returns (address);\\n\\n    /**\\n     * Return the address used for the MAI tokens in vault\\n     *\\n     * @return  The address in question\\n     */\\n    function maiAddress() external view returns (address);\\n\\n    /**\\n     * Return the address used for the LP USDC/MAI tokens in vault\\n     *\\n     * @return  The address in question\\n     */\\n    function lpAddress() external view returns (address);\\n\\n    /**\\n     * Return the address used for the QI tokens in vault\\n     *\\n     * @return  The address in question\\n     */\\n    function qiAddress() external view returns (address);\\n\\n    /**\\n     * Return the address of the QuickSwap Router to talk to\\n     *\\n     * @return  The address in question\\n     */\\n    function quickSwapRouterAddress() external view returns (address);\\n\\n    /**\\n     * Return the address of the QiDao Farm to use\\n     *\\n     * @return  The address in question\\n     */\\n    function qiDaoFarmAddress() external view returns (address);\\n\\n    /**\\n     * Return the pool ID within the QiDao Farm\\n     *\\n     * @return  The pool ID in question\\n     */\\n    function qiDaoPoolId() external view returns (uint256);\\n\\n    // --- Fees - Automatic -----------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the markup fee the use, using `_decimals()` decimals implicitly\\n     *\\n     * @return  The markup fee to use\\n     */\\n    function markupFee() external view returns (RatioWith6Decimals);\\n\\n    /**\\n     * Return the swap fee the use, using `_decimals()` decimals implicitly\\n     *\\n     * @return  The swap fee to use\\n     */\\n    function swapFee() external view returns (RatioWith6Decimals);\\n\\n    // --- Status - Automatic ---------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return wether the Peronio contract has been initialized yet\\n     *\\n     * @return  True whenever the contract has already been initialized, false otherwise\\n     */\\n    function initialized() external view returns (bool);\\n\\n    // --- Decimals -------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the number of decimals the PE token will work with\\n     *\\n     * @return decimals_  This will always be 6\\n     */\\n    function decimals() external view returns (uint8);\\n\\n    // --- Markup fee change ----------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Set the markup fee to the given value (take into account that this will use `_decimals` decimals implicitly)\\n     *\\n     * @param newMarkupFee  New markup fee value\\n     * @return prevMarkupFee  Previous markup fee value\\n     * @custom:emit  MarkupFeeUpdated\\n     */\\n    function setMarkupFee(RatioWith6Decimals newMarkupFee) external returns (RatioWith6Decimals prevMarkupFee);\\n\\n    // --- Initialization -------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Initialize the PE token by providing collateral USDC tokens - initial conversion rate will be set at the given starting ratio\\n     *\\n     * @param usdcAmount  Number of collateral USDC tokens\\n     * @param startingRatio  Initial minting ratio in PE tokens per USDC tokens minted\\n     * @custom:emit  Initialized\\n     */\\n    function initialize(UsdcQuantity usdcAmount, PePerUsdcQuantity startingRatio) external;\\n\\n    // --- State views ----------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the USDC and MAI token reserves present in QuickSwap\\n     *\\n     * @return usdcReserves  Number of USDC tokens in reserve\\n     * @return maiReserves  Number of MAI tokens in reserve\\n     */\\n    function getLpReserves() external view returns (UsdcQuantity usdcReserves, MaiQuantity maiReserves);\\n\\n    /**\\n     * Return the number of LP USDC/MAI tokens on stake at QiDao's Farm\\n     *\\n     * @return lpAmount  Number of LP USDC/MAI token on stake\\n     */\\n    function stakedBalance() external view returns (LpQuantity lpAmount);\\n\\n    /**\\n     * Return the number of USDC and MAI tokens on stake at QiDao's Farm\\n     *\\n     * @return usdcAmount  Number of USDC tokens on stake\\n     * @return maiAmount  Number of MAI tokens on stake\\n     */\\n    function stakedTokens() external view returns (UsdcQuantity usdcAmount, MaiQuantity maiAmount);\\n\\n    /**\\n     * Return the equivalent number of USDC tokens on stake at QiDao's Farm\\n     *\\n     * @return usdcAmount  Total equivalent number of USDC token on stake\\n     */\\n    function stakedValue() external view returns (UsdcQuantity usdcAmount);\\n\\n    /**\\n     * Return the _collateralized_ price in USDC tokens per PE token\\n     *\\n     * @return price  Collateralized price in USDC tokens per PE token\\n     */\\n    function usdcPrice() external view returns (PePerUsdcQuantity price);\\n\\n    /**\\n     * Return the effective _minting_ price in USDC tokens per PE token\\n     *\\n     * @return price  Minting price in USDC tokens per PE token\\n     */\\n    function buyingPrice() external view returns (UsdcPerPeQuantity price);\\n\\n    /**\\n     * Return the ratio of total number of USDC tokens per PE token\\n     *\\n     * @return ratio  Ratio of USDC tokens per PE token, with `_decimal` decimals\\n     */\\n    function collateralRatio() external view returns (UsdcPerPeQuantity ratio);\\n\\n    // --- State changers -------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Mint PE tokens using the provided USDC tokens as collateral --- used by the migrators in order not to incur normal fees\\n     *\\n     * @param to  The address to transfer the minted PE tokens to\\n     * @param usdcAmount  Number of USDC tokens to use as collateral\\n     * @param minReceive  The minimum number of PE tokens to mint\\n     * @return peAmount  The number of PE tokens actually minted\\n     * @custom:emit  Minted\\n     */\\n    function mintForMigration(\\n        address to,\\n        UsdcQuantity usdcAmount,\\n        PeQuantity minReceive\\n    ) external returns (PeQuantity peAmount);\\n\\n    /**\\n     * Mint PE tokens using the provided USDC tokens as collateral\\n     *\\n     * @param to  The address to transfer the minted PE tokens to\\n     * @param usdcAmount  Number of USDC tokens to use as collateral\\n     * @param minReceive  The minimum number of PE tokens to mint\\n     * @return peAmount  The number of PE tokens actually minted\\n     * @custom:emit  Minted\\n     */\\n    function mint(\\n        address to,\\n        UsdcQuantity usdcAmount,\\n        PeQuantity minReceive\\n    ) external returns (PeQuantity peAmount);\\n\\n    /**\\n     * Extract the given number of PE tokens as USDC tokens\\n     *\\n     * @param to  Address to deposit extracted USDC tokens into\\n     * @param peAmount  Number of PE tokens to withdraw\\n     * @return usdcTotal  Number of USDC tokens extracted\\n     * @custom:emit  Withdrawal\\n     */\\n    function withdraw(address to, PeQuantity peAmount) external returns (UsdcQuantity usdcTotal);\\n\\n    /**\\n     * Extract the given number of PE tokens as LP USDC/MAI tokens\\n     *\\n     * @param to  Address to deposit extracted LP USDC/MAI tokens into\\n     * @param peAmount  Number of PE tokens to withdraw liquidity for\\n     * @return lpAmount  Number of LP USDC/MAI tokens extracted\\n     * @custom:emit LiquidityWithdrawal\\n     */\\n    function withdrawLiquidity(address to, PeQuantity peAmount) external returns (LpQuantity lpAmount);\\n\\n    // --- Rewards --------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Return the rewards accrued by staking LP USDC/MAI tokens in QiDao's Farm (in QI tokens)\\n     *\\n     * @return qiAmount  Number of QI tokens accrued\\n     */\\n    function getPendingRewardsAmount() external view returns (QiQuantity qiAmount);\\n\\n    /**\\n     * Claim QiDao's QI token rewards, and re-invest them in the QuickSwap liquidity pool and QiDao's Farm\\n     *\\n     * @return usdcAmount  The number of USDC tokens being re-invested\\n     * @return lpAmount  The number of LP USDC/MAI tokens being put on stake\\n     * @custom:emit CompoundRewards\\n     */\\n    function compoundRewards() external returns (UsdcQuantity usdcAmount, LpQuantity lpAmount);\\n\\n    // --- Quotes ---------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Retrieve the expected number of PE tokens corresponding to the given number of USDC tokens for minting.\\n     *\\n     * @param usdc  Number of USDC tokens to quote for\\n     * @return pe  Number of PE tokens quoted for the given number of USDC tokens\\n     */\\n    function quoteIn(UsdcQuantity usdc) external view returns (PeQuantity pe);\\n\\n    /**\\n     * Retrieve the expected number of USDC tokens corresponding to the given number of PE tokens for withdrawal.\\n     *\\n     * @param pe  Number of PE tokens to quote for\\n     * @return usdc  Number of USDC tokens quoted for the given number of PE tokens\\n     */\\n    function quoteOut(PeQuantity pe) external view returns (UsdcQuantity usdc);\\n}\\n\",\"keccak256\":\"0x1d04021ebd684dbf1d61a6f9c475b14fdf90b5c9d88f77b4cff16f45f33fd669\",\"license\":\"MIT\"},\"contracts/migrations/IMigrator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IMigrator {\\n    // --- Events ---------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Emitted upon migration\\n     *\\n     * @param timestamp  The moment in time when migration took place\\n     * @param oldPe  The number of old PE tokens withdraw from the previous version\\n     * @param usdc  The number of USDC tokens converted from the previous version and into the new version\\n     * @param newPe  The number of new PE tokens migrated to the new version\\n     */\\n    event Migrated(uint256 timestamp, uint256 oldPe, uint256 usdc, uint256 newPe);\\n\\n    // --- Addresses - Automatic ------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Retrieve the old version's address\\n     *\\n     * @return The address in question\\n     */\\n    function peronioV1Address() external view returns (address);\\n\\n    /**\\n     * Retrieve the new version's address\\n     *\\n     * @return The address in question\\n     */\\n    function peronioV2Address() external view returns (address);\\n\\n    // --- Migration Proper -----------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Migrate the given number of PE tokens from the old contract to the new one\\n     *\\n     * @param amount  The number of PE tokens to withdraw from the old contract\\n     * @return usdc  The number of USDC tokens withdrawn from the old contract\\n     * @return pe  The number of PE tokens minted on the new contract\\n     * @custom:emit  Migrated\\n     */\\n    function migrate(uint256 amount) external returns (uint256 usdc, uint256 pe);\\n\\n    // --- Quote ----------------------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Retrieve the number of USDC tokens to withdraw from the old contract, and the number of OE tokens to mint on the new one\\n     *\\n     * @param amount  The number of PE tokens to withdraw from the old contract\\n     * @return usdc  The number of USDC tokens to withdraw from the old contract\\n     * @return pe  The number of PE tokens to mint on the new contract\\n     */\\n    function quote(uint256 amount) external view returns (uint256 usdc, uint256 pe);\\n}\\n\",\"keccak256\":\"0x643e60aa24fd6575a37dcfb9104200fd1c4612da29d4bd754b3696ec1c8e554e\",\"license\":\"MIT\"},\"contracts/migrations/Migrator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {PeronioV1Wrapper} from \\\"./old/PeronioV1Wrapper.sol\\\";\\nimport {IPeronioV1} from \\\"./old/IPeronioV1.sol\\\";\\nimport \\\"../IPeronio.sol\\\";\\n\\nimport {Math} from \\\"@openzeppelin/contracts_latest/utils/math/Math.sol\\\";\\nimport {IUniswapV2Pair} from \\\"../uniswap/interfaces/IUniswapV2Pair.sol\\\";\\nimport {IFarm} from \\\"../qidao/IFarm.sol\\\";\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts_latest/token/ERC20/IERC20.sol\\\";\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n// Interface\\nimport {IMigrator} from \\\"./IMigrator.sol\\\";\\n\\ncontract Migrator is IMigrator, ERC165 {\\n    using PeronioV1Wrapper for IPeronioV1;\\n\\n    // Peronio V1 Address\\n    address public immutable peronioV1Address;\\n\\n    // Peronio V2 Address\\n    address public immutable peronioV2Address;\\n\\n    /**\\n     * Construct a new Peronio migrator\\n     *\\n     * @param _peronioV1Address  The address of the old PE contract\\n     * @param _peronioV2Address  The address of the new PE contract\\n     */\\n    constructor(address _peronioV1Address, address _peronioV2Address) {\\n        // Peronio Addresses\\n        peronioV1Address = _peronioV1Address;\\n        peronioV2Address = _peronioV2Address;\\n\\n        // Unlimited USDC Approve to Peronio V2 contract\\n        IERC20(IPeronioV1(_peronioV1Address).USDC_ADDRESS()).approve(_peronioV2Address, type(uint256).max);\\n    }\\n\\n    /**\\n     * Implementation of the IERC165 interface\\n     *\\n     * @param interfaceId  Interface ID to check against\\n     * @return  Whether the provided interface ID is supported\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IMigrator).interfaceId || super.supportsInterface(interfaceId);\\n    }\\n\\n    // --- Migration Proper -----------------------------------------------------------------------------------------------------------------------------------\\n\\n    /**\\n     * Migrate the given number of PE tokens from the old contract to the new one\\n     *\\n     * @param amount  The number of PE tokens to withdraw from the old contract\\n     * @return usdc  The number of USDC tokens withdrawn from the old contract\\n     * @return pe  The number of PE tokens minted on the new contract\\n     * @custom:emit  Migrated\\n     */\\n    function migrate(uint256 amount) external override returns (uint256 usdc, uint256 pe) {\\n        // Peronio V1 Contract Wrapper\\n        IPeronioV1 peronioV1 = IPeronioV1(peronioV1Address);\\n        // Peronio V2 Contract\\n        IPeronio peronioV2 = IPeronio(peronioV2Address);\\n\\n        // Transfer PE V1 to this contract\\n        IERC20(peronioV1Address).transferFrom(msg.sender, address(this), amount);\\n\\n        // Calculate USDC to be received by Peronio V1\\n        usdc = peronioV1.withdrawV2(address(this), amount);\\n        // Calculate PE to be minted by Peronio V2\\n        pe = PeQuantity.unwrap(peronioV2.mintForMigration(msg.sender, UsdcQuantity.wrap(usdc), PeQuantity.wrap(1)));\\n\\n        // Emit Migrated event\\n        emit Migrated(block.timestamp, amount, usdc, pe);\\n    }\\n\\n    // --- Quote ----------------------------------------------------------------------------------------------------------------------------------------------\\n    //\\n    // Quote is created by inlining the call to migrate, and discarding state-changing statements\\n    //\\n\\n    /**\\n     * Retrieve the number of USDC tokens to withdraw from the old contract, and the number of OE tokens to mint on the new one\\n     *\\n     * @param amount  The number of PE tokens to withdraw from the old contract\\n     * @return usdc  The number of USDC tokens to withdraw from the old contract\\n     * @return pe  The number of PE tokens to mint on the new contract\\n     */\\n    function quote(uint256 amount) external view override returns (uint256 usdc, uint256 pe) {\\n        uint256 usdcReserves;\\n        uint256 maiReserves;\\n        {\\n            (uint112 _usdcReserves, uint112 _maiReserves) = IPeronioV1(peronioV1Address).getLpReserves();\\n            (usdcReserves, maiReserves) = (uint256(_usdcReserves), uint256(_maiReserves));\\n        }\\n\\n        uint256 lpTotalSupply = IERC20(IPeronioV1(peronioV1Address).LP_ADDRESS()).totalSupply();\\n        uint256 kLast = IUniswapV2Pair(IPeronioV1(peronioV1Address).LP_ADDRESS()).kLast();\\n\\n        {\\n            uint256 rootKLast = Math.sqrt(kLast);\\n            uint256 rootK = Math.sqrt(usdcReserves * maiReserves);\\n            if (rootKLast < rootK) {\\n                lpTotalSupply += (lpTotalSupply * (rootK - rootKLast)) / (5 * rootK + rootKLast);\\n            }\\n        }\\n\\n        {\\n            uint256 usdcAmount;\\n            uint256 maiAmount;\\n            {\\n                uint256 newLpBalance = IERC20(IPeronioV1(peronioV1Address).LP_ADDRESS()).balanceOf(IPeronioV1(peronioV1Address).LP_ADDRESS()) +\\n                    (((amount * 10e8) / IERC20(peronioV1Address).totalSupply()) *\\n                        IFarm(IPeronioV1(peronioV1Address).QIDAO_FARM_ADDRESS()).deposited(IPeronioV1(peronioV1Address).QIDAO_POOL_ID(), peronioV1Address)) /\\n                    10e8;\\n                usdcAmount = Math.mulDiv(newLpBalance, usdcReserves, lpTotalSupply);\\n                maiAmount = Math.mulDiv(newLpBalance, maiReserves, lpTotalSupply);\\n                lpTotalSupply -= newLpBalance;\\n            }\\n\\n            usdcReserves -= usdcAmount;\\n            maiReserves -= maiAmount;\\n            kLast = usdcReserves * maiReserves;\\n\\n            {\\n                uint256 usdcAmountOut = Math.mulDiv(997 * maiAmount, usdcReserves, 997 * maiAmount + 1000 * maiReserves);\\n                usdc = usdcAmount + usdcAmountOut;\\n                usdcReserves -= usdcAmountOut;\\n            }\\n        }\\n\\n        uint256 lpAmountMint;\\n        {\\n            uint256 usdcAmount;\\n            uint256 maiAmount;\\n            {\\n                uint256 usdcAmountToSwap = Math.sqrt(Math.mulDiv(3988009 * usdcReserves + 3988000 * usdc, usdcReserves, 3976036)) -\\n                    Math.mulDiv(usdcReserves, 1997, 1994);\\n                uint256 maiAmountOut = Math.mulDiv(997 * usdcAmountToSwap, maiReserves, 997 * usdcAmountToSwap + 1000 * usdcReserves);\\n\\n                usdcReserves += usdcAmountToSwap;\\n                maiReserves -= maiAmountOut;\\n\\n                {\\n                    uint256 amountMaiOptimal = Math.mulDiv(usdc, maiReserves, usdcReserves);\\n                    if (amountMaiOptimal <= maiAmountOut) {\\n                        (usdcAmount, maiAmount) = (usdc, amountMaiOptimal);\\n                    } else {\\n                        uint256 amountUsdcOptimal = (maiAmountOut * usdcReserves) / maiReserves;\\n                        (usdcAmount, maiAmount) = (amountUsdcOptimal, maiAmountOut);\\n                    }\\n                }\\n\\n                {\\n                    uint256 rootK = Math.sqrt(usdcReserves * maiReserves);\\n                    uint256 rootKLast = Math.sqrt(kLast);\\n                    if (rootKLast < rootK) {\\n                        lpTotalSupply += (lpTotalSupply * (rootK - rootKLast)) / (5 * rootK + rootKLast);\\n                    }\\n                }\\n            }\\n\\n            uint8 decimals = IPeronio(peronioV2Address).decimals();\\n            uint256 totalMintFee;\\n            {\\n                (, , , , uint16 depositFeeBP) = IFarm(IPeronio(peronioV2Address).qiDaoFarmAddress()).poolInfo(IPeronio(peronioV2Address).qiDaoPoolId());\\n                totalMintFee = RatioWith6Decimals.unwrap(IPeronio(peronioV2Address).swapFee()) + uint256(depositFeeBP) * 10**(decimals - 4);\\n            }\\n\\n            lpAmountMint = Math.mulDiv(\\n                Math.min(Math.mulDiv(usdcAmount, lpTotalSupply, usdcReserves), Math.mulDiv(maiAmount, lpTotalSupply, maiReserves)),\\n                10**decimals - totalMintFee,\\n                10**decimals\\n            );\\n        }\\n\\n        uint256 stakedAmount = IFarm(IPeronio(peronioV2Address).qiDaoFarmAddress()).deposited(IPeronio(peronioV2Address).qiDaoPoolId(), peronioV2Address);\\n\\n        pe = Math.mulDiv(lpAmountMint, IERC20(peronioV2Address).totalSupply(), stakedAmount);\\n    }\\n}\\n\",\"keccak256\":\"0x5f802648cee02edb89b0bd312f73766910a94931e6695e143db5280ac0c356aa\",\"license\":\"MIT\"},\"contracts/migrations/old/IPeronioV1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IPeronioV1 {\\n    function USDC_ADDRESS() external view returns (address);\\n\\n    function MAI_ADDRESS() external view returns (address);\\n\\n    function LP_ADDRESS() external view returns (address);\\n\\n    function QUICKSWAP_ROUTER_ADDRESS() external view returns (address);\\n\\n    function QIDAO_FARM_ADDRESS() external view returns (address);\\n\\n    function QI_ADDRESS() external view returns (address);\\n\\n    function QIDAO_POOL_ID() external view returns (uint256);\\n\\n    // Markup\\n    function MARKUP_DECIMALS() external view returns (uint8);\\n\\n    function markup() external view returns (uint256);\\n\\n    function swapFee() external view returns (uint256);\\n\\n    // Initialization can only be run once\\n    function initialized() external view returns (bool);\\n\\n    // Roles\\n    function MARKUP_ROLE() external view returns (bytes32);\\n\\n    function REWARDS_ROLE() external view returns (bytes32);\\n\\n    // Events\\n    event Initialized(address owner, uint256 collateral, uint256 startingRatio);\\n    event Minted(address indexed to, uint256 collateralAmount, uint256 tokenAmount);\\n    event Withdrawal(address indexed to, uint256 collateralAmount, uint256 tokenAmount);\\n    event MarkupUpdated(address operator, uint256 markup);\\n    event CompoundRewards(uint256 qi, uint256 usdc, uint256 lp);\\n    event HarvestedMatic(uint256 wmatic, uint256 collateral);\\n\\n    function decimals() external view returns (uint8);\\n\\n    function initialize(uint256 usdcAmount, uint256 startingRatio) external;\\n\\n    function setMarkup(uint256 markup_) external;\\n\\n    function mint(\\n        address to,\\n        uint256 usdcAmount,\\n        uint256 minReceive\\n    ) external returns (uint256 peAmount);\\n\\n    function withdraw(address to, uint256 peAmount) external;\\n\\n    function claimRewards() external;\\n\\n    function compoundRewards() external returns (uint256 usdcAmount, uint256 lpAmount);\\n\\n    function stakedBalance() external view returns (uint256);\\n\\n    function stakedValue() external view returns (uint256 totalUSDC);\\n\\n    function usdcPrice() external view returns (uint256);\\n\\n    function buyingPrice() external view returns (uint256);\\n\\n    function collateralRatio() external view returns (uint256);\\n\\n    function getPendingRewardsAmount() external view returns (uint256 amount);\\n\\n    function getLpReserves() external view returns (uint112 usdcReserves, uint112 maiReserves);\\n}\\n\",\"keccak256\":\"0x928b763ddcceb0a8254b8a8c66c27b6964ff062a8cef559c7aec731a722dd65e\",\"license\":\"MIT\"},\"contracts/migrations/old/PeronioV1Wrapper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\n// Peronio V1 Interface\\nimport {IPeronioV1} from \\\"./IPeronioV1.sol\\\";\\n\\n// ERC20 Interface\\nimport {IERC20} from \\\"@openzeppelin/contracts_latest/token/ERC20/IERC20.sol\\\";\\n\\n// QiDao\\nimport {IFarm} from \\\"../../qidao/IFarm.sol\\\";\\n\\n// UniSwap\\nimport {IUniswapV2Pair} from \\\"../../uniswap/interfaces/IUniswapV2Pair.sol\\\";\\nimport {IERC20Uniswap} from \\\"../../uniswap/interfaces/IERC20Uniswap.sol\\\";\\n\\nimport {Math} from \\\"@openzeppelin/contracts_latest/utils/math/Math.sol\\\";\\n\\nlibrary PeronioV1Wrapper {\\n    /**\\n     * Retrieve the expected number of USDC tokens corresponding to the given number of PE tokens for withdrawal.\\n     *\\n     * @param peronioContract  Peronio contract interface\\n     * @param pe  Number of PE tokens to quote for\\n     * @return usdc  Number of USDC tokens quoted for the given number of PE tokens\\n     */\\n    function quoteOut(IPeronioV1 peronioContract, uint256 pe) internal view returns (uint256 usdc) {\\n        // --- Gas Saving -------------------------------------------------------------------------\\n        address _lpAddress = peronioContract.LP_ADDRESS();\\n\\n        (uint256 usdcReserves, uint256 maiReserves) = peronioContract.getLpReserves();\\n        uint256 lpTotalSupply = IERC20(_lpAddress).totalSupply();\\n\\n        // deal with LP minting when changing its K\\n        {\\n            uint256 rootK = Math.sqrt(usdcReserves * maiReserves);\\n            uint256 rootKLast = Math.sqrt(IUniswapV2Pair(_lpAddress).kLast());\\n            if (rootKLast < rootK) {\\n                lpTotalSupply += Math.mulDiv(lpTotalSupply, rootK - rootKLast, (rootK * 5) + rootKLast);\\n            }\\n        }\\n\\n        // calculate LP values actually withdrawn\\n        uint256 lpAmount = IERC20Uniswap(_lpAddress).balanceOf(_lpAddress) +\\n            Math.mulDiv(pe, peronioContract.stakedBalance(), IERC20(address(peronioContract)).totalSupply());\\n\\n        uint256 usdcAmount = Math.mulDiv(usdcReserves, lpAmount, lpTotalSupply);\\n        uint256 maiAmount = Math.mulDiv(maiReserves, lpAmount, lpTotalSupply);\\n\\n        usdc = usdcAmount + _getAmountOut(maiAmount, maiReserves - maiAmount, usdcReserves - usdcAmount);\\n    }\\n\\n    /**\\n     * Extract the given number of PE tokens as USDC tokens\\n     *\\n     * @param peronioContract  Peronio contract interface\\n     * @param to  Address to deposit extracted USDC tokens into\\n     * @param peAmount  Number of PE tokens to withdraw\\n     * @return usdcTotal  Number of USDC tokens extracted\\n     * @custom:emit  Withdrawal\\n     */\\n    function withdrawV2(\\n        IPeronioV1 peronioContract,\\n        address to,\\n        uint256 peAmount\\n    ) internal returns (uint256 usdcTotal) {\\n        address usdcAddress = peronioContract.USDC_ADDRESS();\\n        uint256 oldUsdcBalance = IERC20(usdcAddress).balanceOf(to);\\n\\n        peronioContract.withdraw(to, peAmount);\\n\\n        usdcTotal = IERC20(usdcAddress).balanceOf(to) - oldUsdcBalance;\\n    }\\n\\n    function _getAmountOut(\\n        uint256 amountIn,\\n        uint256 reserveIn,\\n        uint256 reserveOut\\n    ) internal pure returns (uint256 amountOut) {\\n        uint256 amountInWithFee = amountIn * 997;\\n        amountOut = Math.mulDiv(amountInWithFee, reserveOut, reserveIn * 1000 + amountInWithFee);\\n    }\\n}\\n\",\"keccak256\":\"0x059b5bd44f6791600e524fc60ededdd6c98fd6f3f569899fd4a6c68f82447477\",\"license\":\"MIT\"},\"contracts/qidao/IFarm.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IFarm {\\n    function add(\\n        uint256 _allocPoint,\\n        address _lpToken,\\n        bool _withUpdate,\\n        uint16 _depositFeeBP\\n    ) external;\\n\\n    function deposit(uint256 _pid, uint256 _amount) external;\\n\\n    function deposited(uint256 _pid, address _user) external view returns (uint256);\\n\\n    function emergencyWithdraw(uint256 _pid) external;\\n\\n    function endBlock() external view returns (uint256);\\n\\n    function erc20() external view returns (address);\\n\\n    function feeAddress() external view returns (address);\\n\\n    function fund(uint256 _amount) external;\\n\\n    function massUpdatePools() external;\\n\\n    function owner() external view returns (address);\\n\\n    function paidOut() external view returns (uint256);\\n\\n    function pending(uint256 _pid, address _user) external view returns (uint256);\\n\\n    function poolInfo(uint256)\\n        external\\n        view\\n        returns (\\n            address lpToken,\\n            uint256 allocPoint,\\n            uint256 lastRewardBlock,\\n            uint256 accERC20PerShare,\\n            uint16 depositFeeBP\\n        );\\n\\n    function poolLength() external view returns (uint256);\\n\\n    function renounceOwnership() external;\\n\\n    function rewardPerBlock() external view returns (uint256);\\n\\n    function set(\\n        uint256 _pid,\\n        uint256 _allocPoint,\\n        bool _withUpdate\\n    ) external;\\n\\n    function setFeeAddress(address _feeAddress) external;\\n\\n    function startBlock() external view returns (uint256);\\n\\n    function totalAllocPoint() external view returns (uint256);\\n\\n    function totalPending() external view returns (uint256);\\n\\n    function transferOwnership(address newOwner) external;\\n\\n    function updatePool(uint256 _pid) external;\\n\\n    function userInfo(uint256, address) external view returns (uint256 amount, uint256 rewardDebt);\\n\\n    function withdraw(uint256 _pid, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xa9f4ab1afb324e3be8c35fa310fd8c23b614349487f606c9b4dcb8408b8e9a06\",\"license\":\"MIT\"},\"contracts/uniswap/interfaces/IERC20Uniswap.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.17;\\n\\ninterface IERC20Uniswap {\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    function name() external view returns (string memory);\\n\\n    function symbol() external view returns (string memory);\\n\\n    function decimals() external view returns (uint8);\\n\\n    function totalSupply() external view returns (uint256);\\n\\n    function balanceOf(address owner) external view returns (uint256);\\n\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    function approve(address spender, uint256 value) external returns (bool);\\n\\n    function transfer(address to, uint256 value) external returns (bool);\\n\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 value\\n    ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x667e2925be913b69db034b03fa1ce3606bd947d74520ba0313a70f32d0cab88a\",\"license\":\"GPL-3.0\"},\"contracts/uniswap/interfaces/IUniswapV2Pair.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.17;\\n\\ninterface IUniswapV2Pair {\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    function NAME() external pure returns (string memory);\\n\\n    function SYMBOL() external pure returns (string memory);\\n\\n    function DECIMALS() external pure returns (uint8);\\n\\n    function totalSupply() external view returns (uint256);\\n\\n    function balanceOf(address owner) external view returns (uint256);\\n\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    function approve(address spender, uint256 value) external returns (bool);\\n\\n    function transfer(address to, uint256 value) external returns (bool);\\n\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 value\\n    ) external returns (bool);\\n\\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\\n\\n    function nonces(address owner) external view returns (uint256);\\n\\n    function permit(\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) external;\\n\\n    event Mint(address indexed sender, uint256 amount0, uint256 amount1);\\n    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);\\n    event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);\\n    event Sync(uint112 reserve0, uint112 reserve1);\\n\\n    function MINIMUM_LIQUIDITY() external pure returns (uint256);\\n\\n    function factory() external view returns (address);\\n\\n    function token0() external view returns (address);\\n\\n    function token1() external view returns (address);\\n\\n    function getReserves()\\n        external\\n        view\\n        returns (\\n            uint112 reserve0,\\n            uint112 reserve1,\\n            uint32 blockTimestampLast\\n        );\\n\\n    function price0CumulativeLast() external view returns (uint256);\\n\\n    function price1CumulativeLast() external view returns (uint256);\\n\\n    function kLast() external view returns (uint256);\\n\\n    function mint(address to) external returns (uint256 liquidity);\\n\\n    function burn(address to) external returns (uint256 amount0, uint256 amount1);\\n\\n    function swap(\\n        uint256 amount0Out,\\n        uint256 amount1Out,\\n        address to,\\n        bytes calldata data\\n    ) external;\\n\\n    function skim(address to) external;\\n\\n    function sync() external;\\n\\n    function initialize(address, address) external;\\n}\\n\",\"keccak256\":\"0x5be83d2f9dcded80ff5ae74ca2544b58110b2a2e67ea1cc8d832aefe202ee168\",\"license\":\"GPL-3.0\"}},\"version\":1}",
  "bytecode": "0x60c06040523480156200001157600080fd5b5060405162001bf438038062001bf483398101604081905262000034916200014b565b6001600160a01b03808316608081905290821660a0526040805163bb09d9b760e01b8152905163bb09d9b7916004808201926020929091908290030181865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac919062000183565b60405163095ea7b360e01b81526001600160a01b0383811660048301526000196024830152919091169063095ea7b3906044016020604051808303816000875af1158015620000ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001259190620001a8565b505050620001cc565b80516001600160a01b03811681146200014657600080fd5b919050565b600080604083850312156200015f57600080fd5b6200016a836200012e565b91506200017a602084016200012e565b90509250929050565b6000602082840312156200019657600080fd5b620001a1826200012e565b9392505050565b600060208284031215620001bb57600080fd5b81518015158114620001a157600080fd5b60805160a05161197e620002766000396000818160c10152818161023001528181610c8701528181610d0e01528181610d9e01528181610eab01528181610f8401528181611014015281816110d201526111430152600081816101000152818161020e015281816103ad0152818161046001528181610547015281816106a401528181610734015281816107f20152818161085d0152818161090b015261099b015261197e6000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063463698f311610050578063463698f3146100bc57806355c96dfc146100fb578063ed1bd76c1461012257600080fd5b806301ffc9a71461006c578063454b060814610094575b600080fd5b61007f61007a366004611615565b610135565b60405190151581526020015b60405180910390f35b6100a76100a2366004611657565b6101ce565b6040805192835260208301919091520161008b565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161008b565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6100a7610130366004611657565b6103a2565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fbbaf246b0000000000000000000000000000000000000000000000000000000014806101c857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810182905260009081907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b038316906323b872dd906064016020604051808303816000875af1158015610283573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a79190611670565b506102bc6001600160a01b03831630876111d6565b6040517f5204363e00000000000000000000000000000000000000000000000000000000815233600482015260248101829052600160448201529094506001600160a01b03821690635204363e906064016020604051808303816000875af115801561032c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103509190611692565b6040805142815260208101889052908101869052606081018290529093507f3b8612735a70b2eb93900d517ea0486036481fe450a9c9f5681491d32ed06c669060800160405180910390a15050915091565b6000806000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b282e0f96040518163ffffffff1660e01b81526004016040805180830381865afa158015610408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042c91906116ce565b91509150816dffffffffffffffffffffffffffff16816dffffffffffffffffffffffffffff168094508195505050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e09190611718565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561051d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105419190611692565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611718565b6001600160a01b0316637464fc3d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106289190611692565b90506000610635826113dc565b9050600061064b6106468688611749565b6113dc565b9050808210156106965781610661826005611749565b61066b9190611760565b6106758383611773565b61067f9086611749565b610689919061179c565b6106939085611760565b93505b50506000806000633b9aca007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663491116176040518163ffffffff1660e01b8152600401602060405180830381865afa158015610700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107249190611718565b6001600160a01b031663a23831067f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d4f09d026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b49190611692565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260048101919091526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401602060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190611692565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dd9190611692565b6108eb8d633b9aca00611749565b6108f5919061179c565b6108ff9190611749565b610909919061179c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190611718565b6001600160a01b03166370a082317f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1b9190611718565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b9190611692565b610aa59190611760565b9050610ab281888761154a565b9250610abf81878761154a565b9150610acb8186611773565b9450610ad990508287611773565b9550610ae58186611773565b9450610af18587611749565b92506000610b2c610b04836103e5611749565b88610b11896103e8611749565b610b1d866103e5611749565b610b279190611760565b61154a565b9050610b388184611760565b9850610b448188611773565b9650505050600080600080610b5e886107cd6107ca61154a565b610b92610646610b718d623cda20611749565b610b7e8c623cda29611749565b610b889190611760565b8b623cab6461154a565b610b9c9190611773565b90506000610bbc610baf836103e5611749565b89610b118c6103e8611749565b9050610bc8828a611760565b9850610bd48189611773565b97506000610be38c8a8c61154a565b9050818111610bf7578b9450925082610c17565b600089610c048c85611749565b610c0e919061179c565b95509193508391505b506000610c276106468a8c611749565b90506000610c34886113dc565b905081811015610c7f5780610c4a836005611749565b610c549190611760565b610c5e8284611773565b610c68908b611749565b610c72919061179c565b610c7c908a611760565b98505b5050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0791906117be565b90506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c7c6f016040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e9190611718565b6001600160a01b0316631526fe277f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373956bc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1e9190611692565b6040518263ffffffff1660e01b8152600401610e3c91815260200190565b60a060405180830381865afa158015610e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7d91906117e1565b945050505050600483610e90919061183c565b610e9b90600a611939565b610ea99061ffff8316611749565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166354cf2aeb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b9190611692565b610f359190611760565b915050610f7a610f59610f49868a8d61154a565b610f54868b8d61154a565b6115ff565b82610f6585600a611939565b610f6f9190611773565b610b2785600a611939565b94505050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c7c6f016040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110049190611718565b6001600160a01b031663a23831067f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373956bc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611070573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110949190611692565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260048101919091526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401602060405180830381865afa158015611117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113b9190611692565b90506111c9827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561119f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c39190611692565b8361154a565b9650505050505050915091565b600080846001600160a01b031663bb09d9b76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190611718565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301529192506000918316906370a0823190602401602060405180830381865afa1580156112a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c49190611692565b6040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790529192509087169063f3fef3a390604401600060405180830381600087803b15801561132b57600080fd5b505af115801561133f573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152849350851691506370a0823190602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c89190611692565b6113d29190611773565b9695505050505050565b6000816000036113ee57506000919050565b600182608081901c156114065760409190911b9060801c5b604081901c1561141b5760209190911b9060401c5b602081901c156114305760109190911b9060201c5b601081901c156114455760089190911b9060101c5b600881901c1561145a5760049190911b9060081c5b600481901c1561146f5760029190911b9060041c5b600281901c1561148157600182901b91505b600182858161149257611492611786565b048301901c915060018285816114aa576114aa611786565b048301901c915060018285816114c2576114c2611786565b048301901c915060018285816114da576114da611786565b048301901c915060018285816114f2576114f2611786565b048301901c9150600182858161150a5761150a611786565b048301901c9150600182858161152257611522611786565b048301901c91506115428283868161153c5761153c611786565b046115ff565b949350505050565b60008080600019858709858702925082811083820303915050806000036115845783828161157a5761157a611786565b04925050506115f8565b80841161159057600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600081831061160e57816115f8565b5090919050565b60006020828403121561162757600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146115f857600080fd5b60006020828403121561166957600080fd5b5035919050565b60006020828403121561168257600080fd5b815180151581146115f857600080fd5b6000602082840312156116a457600080fd5b5051919050565b80516dffffffffffffffffffffffffffff811681146116c957600080fd5b919050565b600080604083850312156116e157600080fd5b6116ea836116ab565b91506116f8602084016116ab565b90509250929050565b80516001600160a01b03811681146116c957600080fd5b60006020828403121561172a57600080fd5b6115f882611701565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176101c8576101c8611733565b808201808211156101c8576101c8611733565b818103818111156101c8576101c8611733565b634e487b7160e01b600052601260045260246000fd5b6000826117b957634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156117d057600080fd5b815160ff811681146115f857600080fd5b600080600080600060a086880312156117f957600080fd5b61180286611701565b9450602086015193506040860151925060608601519150608086015161ffff8116811461182e57600080fd5b809150509295509295909350565b60ff82811682821603908111156101c8576101c8611733565b600181815b8085111561189057816000190482111561187657611876611733565b8085161561188357918102915b93841c939080029061185a565b509250929050565b6000826118a7575060016101c8565b816118b4575060006101c8565b81600181146118ca57600281146118d4576118f0565b60019150506101c8565b60ff8411156118e5576118e5611733565b50506001821b6101c8565b5060208310610133831016604e8410600b8410161715611913575081810a6101c8565b61191d8383611855565b806000190482111561193157611931611733565b029392505050565b60006115f860ff84168361189856fea2646970667358221220c479af2724a87d248f9816768355a2ff0815d459dfb4d32ea4b7b7e87e2e119764736f6c63430008110033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063463698f311610050578063463698f3146100bc57806355c96dfc146100fb578063ed1bd76c1461012257600080fd5b806301ffc9a71461006c578063454b060814610094575b600080fd5b61007f61007a366004611615565b610135565b60405190151581526020015b60405180910390f35b6100a76100a2366004611657565b6101ce565b6040805192835260208301919091520161008b565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161008b565b6100e37f000000000000000000000000000000000000000000000000000000000000000081565b6100a7610130366004611657565b6103a2565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fbbaf246b0000000000000000000000000000000000000000000000000000000014806101c857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810182905260009081907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b038316906323b872dd906064016020604051808303816000875af1158015610283573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a79190611670565b506102bc6001600160a01b03831630876111d6565b6040517f5204363e00000000000000000000000000000000000000000000000000000000815233600482015260248101829052600160448201529094506001600160a01b03821690635204363e906064016020604051808303816000875af115801561032c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103509190611692565b6040805142815260208101889052908101869052606081018290529093507f3b8612735a70b2eb93900d517ea0486036481fe450a9c9f5681491d32ed06c669060800160405180910390a15050915091565b6000806000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b282e0f96040518163ffffffff1660e01b81526004016040805180830381865afa158015610408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042c91906116ce565b91509150816dffffffffffffffffffffffffffff16816dffffffffffffffffffffffffffff168094508195505050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e09190611718565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561051d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105419190611692565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611718565b6001600160a01b0316637464fc3d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106289190611692565b90506000610635826113dc565b9050600061064b6106468688611749565b6113dc565b9050808210156106965781610661826005611749565b61066b9190611760565b6106758383611773565b61067f9086611749565b610689919061179c565b6106939085611760565b93505b50506000806000633b9aca007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663491116176040518163ffffffff1660e01b8152600401602060405180830381865afa158015610700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107249190611718565b6001600160a01b031663a23831067f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d4f09d026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b49190611692565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260048101919091526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401602060405180830381865afa158015610837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085b9190611692565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dd9190611692565b6108eb8d633b9aca00611749565b6108f5919061179c565b6108ff9190611749565b610909919061179c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190611718565b6001600160a01b03166370a082317f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d56cf10f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1b9190611718565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b9190611692565b610aa59190611760565b9050610ab281888761154a565b9250610abf81878761154a565b9150610acb8186611773565b9450610ad990508287611773565b9550610ae58186611773565b9450610af18587611749565b92506000610b2c610b04836103e5611749565b88610b11896103e8611749565b610b1d866103e5611749565b610b279190611760565b61154a565b9050610b388184611760565b9850610b448188611773565b9650505050600080600080610b5e886107cd6107ca61154a565b610b92610646610b718d623cda20611749565b610b7e8c623cda29611749565b610b889190611760565b8b623cab6461154a565b610b9c9190611773565b90506000610bbc610baf836103e5611749565b89610b118c6103e8611749565b9050610bc8828a611760565b9850610bd48189611773565b97506000610be38c8a8c61154a565b9050818111610bf7578b9450925082610c17565b600089610c048c85611749565b610c0e919061179c565b95509193508391505b506000610c276106468a8c611749565b90506000610c34886113dc565b905081811015610c7f5780610c4a836005611749565b610c549190611760565b610c5e8284611773565b610c68908b611749565b610c72919061179c565b610c7c908a611760565b98505b5050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0791906117be565b90506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c7c6f016040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e9190611718565b6001600160a01b0316631526fe277f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373956bc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1e9190611692565b6040518263ffffffff1660e01b8152600401610e3c91815260200190565b60a060405180830381865afa158015610e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7d91906117e1565b945050505050600483610e90919061183c565b610e9b90600a611939565b610ea99061ffff8316611749565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166354cf2aeb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b9190611692565b610f359190611760565b915050610f7a610f59610f49868a8d61154a565b610f54868b8d61154a565b6115ff565b82610f6585600a611939565b610f6f9190611773565b610b2785600a611939565b94505050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c7c6f016040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110049190611718565b6001600160a01b031663a23831067f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166373956bc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611070573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110949190611692565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260048101919091526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401602060405180830381865afa158015611117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113b9190611692565b90506111c9827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561119f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c39190611692565b8361154a565b9650505050505050915091565b600080846001600160a01b031663bb09d9b76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190611718565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301529192506000918316906370a0823190602401602060405180830381865afa1580156112a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c49190611692565b6040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790529192509087169063f3fef3a390604401600060405180830381600087803b15801561132b57600080fd5b505af115801561133f573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152849350851691506370a0823190602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c89190611692565b6113d29190611773565b9695505050505050565b6000816000036113ee57506000919050565b600182608081901c156114065760409190911b9060801c5b604081901c1561141b5760209190911b9060401c5b602081901c156114305760109190911b9060201c5b601081901c156114455760089190911b9060101c5b600881901c1561145a5760049190911b9060081c5b600481901c1561146f5760029190911b9060041c5b600281901c1561148157600182901b91505b600182858161149257611492611786565b048301901c915060018285816114aa576114aa611786565b048301901c915060018285816114c2576114c2611786565b048301901c915060018285816114da576114da611786565b048301901c915060018285816114f2576114f2611786565b048301901c9150600182858161150a5761150a611786565b048301901c9150600182858161152257611522611786565b048301901c91506115428283868161153c5761153c611786565b046115ff565b949350505050565b60008080600019858709858702925082811083820303915050806000036115845783828161157a5761157a611786565b04925050506115f8565b80841161159057600080fd5b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b600081831061160e57816115f8565b5090919050565b60006020828403121561162757600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146115f857600080fd5b60006020828403121561166957600080fd5b5035919050565b60006020828403121561168257600080fd5b815180151581146115f857600080fd5b6000602082840312156116a457600080fd5b5051919050565b80516dffffffffffffffffffffffffffff811681146116c957600080fd5b919050565b600080604083850312156116e157600080fd5b6116ea836116ab565b91506116f8602084016116ab565b90509250929050565b80516001600160a01b03811681146116c957600080fd5b60006020828403121561172a57600080fd5b6115f882611701565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176101c8576101c8611733565b808201808211156101c8576101c8611733565b818103818111156101c8576101c8611733565b634e487b7160e01b600052601260045260246000fd5b6000826117b957634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156117d057600080fd5b815160ff811681146115f857600080fd5b600080600080600060a086880312156117f957600080fd5b61180286611701565b9450602086015193506040860151925060608601519150608086015161ffff8116811461182e57600080fd5b809150509295509295909350565b60ff82811682821603908111156101c8576101c8611733565b600181815b8085111561189057816000190482111561187657611876611733565b8085161561188357918102915b93841c939080029061185a565b509250929050565b6000826118a7575060016101c8565b816118b4575060006101c8565b81600181146118ca57600281146118d4576118f0565b60019150506101c8565b60ff8411156118e5576118e5611733565b50506001821b6101c8565b5060208310610133831016604e8410600b8410161715611913575081810a6101c8565b61191d8383611855565b806000190482111561193157611931611733565b029392505050565b60006115f860ff84168361189856fea2646970667358221220c479af2724a87d248f9816768355a2ff0815d459dfb4d32ea4b7b7e87e2e119764736f6c63430008110033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "constructor": {
        "params": {
          "_peronioV1Address": "The address of the old PE contract",
          "_peronioV2Address": "The address of the new PE contract"
        }
      },
      "migrate(uint256)": {
        "custom:emit": "Migrated",
        "params": {
          "amount": "The number of PE tokens to withdraw from the old contract"
        },
        "returns": {
          "pe": " The number of PE tokens minted on the new contract",
          "usdc": " The number of USDC tokens withdrawn from the old contract"
        }
      },
      "quote(uint256)": {
        "params": {
          "amount": "The number of PE tokens to withdraw from the old contract"
        },
        "returns": {
          "pe": " The number of PE tokens to mint on the new contract",
          "usdc": " The number of USDC tokens to withdraw from the old contract"
        }
      },
      "supportsInterface(bytes4)": {
        "params": {
          "interfaceId": "Interface ID to check against"
        },
        "returns": {
          "_0": "Whether the provided interface ID is supported"
        }
      }
    },
    "stateVariables": {
      "peronioV1Address": {
        "return": "The address in question",
        "returns": {
          "_0": "The address in question"
        }
      },
      "peronioV2Address": {
        "return": "The address in question",
        "returns": {
          "_0": "The address in question"
        }
      }
    },
    "version": 1
  },
  "userdoc": {
    "events": {
      "Migrated(uint256,uint256,uint256,uint256)": {
        "notice": "Emitted upon migration"
      }
    },
    "kind": "user",
    "methods": {
      "constructor": {
        "notice": "Construct a new Peronio migrator"
      },
      "migrate(uint256)": {
        "notice": "Migrate the given number of PE tokens from the old contract to the new one"
      },
      "peronioV1Address()": {
        "notice": "Retrieve the old version's address"
      },
      "peronioV2Address()": {
        "notice": "Retrieve the new version's address"
      },
      "quote(uint256)": {
        "notice": "Retrieve the number of USDC tokens to withdraw from the old contract, and the number of OE tokens to mint on the new one"
      },
      "supportsInterface(bytes4)": {
        "notice": "Implementation of the IERC165 interface"
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}